The situation is similar yet different in both languages, C++ or Java.
When the exception is thrown, it propagates back up the stack, looking for a handler. In C++ or Java, it might never find one and thus unwind all the way back to the start and terminate the program. In Java, there is a concept of checked exceptions which enforce that there will be some kind of handling of the exception (if checked). In C++, there is a concept of exception specification, but it is impractical (ill-designed) and should not be used, so, consider all exceptions as "unchecked" in C++.
Whether the exception ends up terminating the program or being caught somewhere far up-stream of where it was thrown, the unwinding process leading up to that is what matters. If it ends up terminating the program, then, of course, there are no memory leaks as the OS reclaims the memory. What you have to worry about is:
As the stack unwinding occurs, in C++, the guarantee is, simply put, that every stack-bound object that was fully constructed (including the data members or base class instance of an object being constructed) will be destroyed immediately (i.e., deterministically) in the exact reverse order in which they were created. So, as long as all resources are tied directly to the construction / destruction of objects (also called "RAII") there will be no leaks (of memory or other resource) during the unwinding process since every resource successfully acquired will be freed (unless freeing the resource fails during unwinding, which is something you need to handle with care).
In Java, the "stack" unwinding occurs in the same fashion, except that instead of immed