views:

257

answers:

7

The general rule, only objects allocated in the free store can cause memory leaks. But objects created in the stack doesn't.

Here is my doubt,

int main()
    {
      myclass x;

      ...

      throw;

      ...
    }

If throw is not handled, it calls, terminate(), which in turn calls abort() and crashes the application. At this time, the objects in the stack are not destoryed (The destructor is not invoked).

My understanding is "When the application terminates (either by abort or by normal exit), it frees all the memory that was allocated for the application". Thus this cannot be considered as memory leak.

Am I correct?

+2  A: 

The answer is, it depends on the OS. I can't think of a modern OS that does not do it this way. But old systems (I think up to win 3.1 in windows, and some old embedded Linux platforms) if the program closed without releasing its memory requests the OS would hold them until you rebooted.

Scott Chamberlain
+4  A: 

edit: as mentioned by GMan, "throw;" re-throws a previously thrown exception, or if there is none, immediately terminates. Since there is none in this case, immediate termination is the result.

Terminating a process always cleans up any leftover userland memory in any modern OS, so is not typically considered a "memory leak", which is defined as unreferenced memory not deallocated in a running process. However, it's really up to the OS as to whether such a thing is considered a "memory leak".

samkass
Whether or not the destructors are called in this case is implementation-defined, yet you make a guarantee. (It's not throwing any exceptions.)
GMan
In my case, the destructor is not called. Thus, I've posted the question.
GMan is correct... since the "throw" is not throwing any exception in this case. "throw;" alone re-throws a previously thrown exception, which you don't have. Since there is no previously thrown exception, it immediately terminates.So whether it's a "memory leak" is then defined by the operating system on which you're running. There are no current OSes I know of that don't clean up a terminated process's memory, but it's up to the OS to prevent a memory leak in this case.
samkass
+1  A: 

Memory leaks are considered a problem because a long running application will slowly bleed away system memory and may in the worst case make the whole machine unusable due to low memory conditions. In your case, the application terminates and all memory allocated to the application will be given back to the system, so hardly a problem.

doron
Thanks Deus. Good answer.
+4  A: 

In a hosted environment (e.g. your typical Unix / Windows / Mac OS X, even DOS, machine) when the application terminates all the memory it occupied is automatically reclaimed by the operating system. Therefore, it doesn't make sense to worry about such memory leaks.

In some cases, before an application terminates, you may want to release all the dynamic memory you allocated in order to detect potential memory leaks through a leak detector, like valgrind. However, even in such a case, the example you describe wouldn't be considered a memory leak.

In general, failing to call a destructor is not the same as causing a memory leak. Memory leaks stem from memory allocated on the heap (with new or malloc or container allocators). Memory allocated on the stack is automatically reclaimed when the stack is unwound. However, if an object holds some other resource (say a file or a window handle), failing to call its destructor will call a resource leak, which can also be a problem. Again, modern OSs will reclaim their resources when an application terminates.

Diomidis Spinellis
Excellent explanation. Thanks.
Solid explanation, but as Dennis points out above - some resources may not be automatically reclaimed: e.g. shared memory segments, locks therein, files that the app. would normally delete.
Tony
+1  A: 

The real question is, "Does myclass allocate any memory itself that must be free/deleted?"

If it does not -- if the only memory it uses is it's internal members -- then it exists entirely on the stack. Once it leaves that function (however it does), the memory on the stack is reclaimed and reused. myclass is gone. That's just the way stacks work.

If myclass does allocate memory that needs to be freed in it's dtor, then you are still in luck, as the dtor will be called as the stack is unwound during the throw. The dtor will have already been called before the exception is declared unhandled and terminate is called.

The only place you will have a problem is if myclass has a dtor, and the dtor throws as exception of it own. The second throw occurring during the stack unwind from the first throw will have it call terminate immedaitely without any more dtors being called.

James Curran
A: 

My understanding is "When the application terminates (either by abort or by normal exit), it frees all the memory that was allocated for the application". Thus this cannot be considered as memory leak.

Am I correct?

Memory leak is a type of programming error which is ranked somewhat lower on scale of programming errors - compared to the uncaught exception.

IOW, if program doesn't terminate properly, a.k.a. crashes, then it is too soon to speak about memory leaks.

On other note, most memory analyzers I have worked with over past decade would not trigger any memory leak alarm in the case - because they do not trigger any alarms when program dumbly crashes. One first has to make program not crashing, only then debug the memory leaks.

Dummy00001
+1  A: 

From OP,

If throw is not handled, it calls, terminate(), which in turn calls abort() and crashes the application. At this time, the objects in the stack are not destoryed (The destructor is not invoked).

This is an implementation defined behavior.

$15.3/9- "If no matching handler is found in a program, the function terminate() is called; whether or not the stack is unwound before this call to terminate() is implementation-defined (15.5.1)."

Therefore, whether this constitues a memory leak or not is also implementation defined behavior, I guess.

Chubsdad
Thanks Chubsdad. That is a good explanation.