3

I am working on a school assignment, and we were told that whenever we have an input error we should print a message and exit the program. Obviously I use exit(1), but the problem is I have memory leaks when using this functions. I don't understand why - every single variable I've used was on the stack and not on the heap.

What should I do to prevent those memory leaks? Thanks!

Luchian Grigore
  • 253,575
  • 64
  • 457
  • 625
yotamoo
  • 5,334
  • 13
  • 49
  • 61
  • 4
    How do you know you have memory leaks? – Andreas Brinck Sep 14 '11 at 09:30
  • 1
    This would be a lot easier to answer if you provided some minimal code that you believe contains a memory leak. – Mankarse Sep 14 '11 at 09:37
  • 7
    It seems you're confused about terminology. A *memory leak* is to accumulate ever more allocated memory (that will not ever be used again) while the process is running. This is meaningless in the context of terminating the process. With a normal termination you can however get some indication whether there has been a memory leak or not, namely by checking whether there are still allocated blocks. Some tools do that. It is quite meaningless for a call to `exit` (or `abort`), where destructors of local objects are not called. I suspect you are basing your opinion on such a meaningless check. – Cheers and hth. - Alf Sep 14 '11 at 09:43
  • @Alf P. Steinbach: best answer! :) – tauran Sep 14 '11 at 09:48
  • @Alf: It's not "meaningless" at all. For there to be memory still in use at program termination is _the_ indication that you have a leak in your code. This is what `valgrind` looks out for, for example. And, yes, [`exit`/`abort` terminate the program without invoking destructors for objects of automatic storage duration](http://stackoverflow.com/questions/397075/what-is-the-difference-between-exit-and-abort/397081#397081). – Lightness Races in Orbit Sep 15 '11 at 12:06

4 Answers4

7

When using the exit function, your program will terminate and all memory allocated by it will be released. There will be no memory leak.

EDIT: From your comments, I can understand you're concerned that your objects aren't destroyed before termination (i.e. their destructor isn't called). This however doesn't constitute a memory leak, since the memory is released by the process and made available to the system. If you're counting on object destructors to perform operations important to your workflow, I suggest returning an error code instead of using exit and propagate that error code up to main().

EDIT2:

According to the standard, calling exit() during the destruction of an object with static storage duration results in undefined behavior. Are you doing that?

Luchian Grigore
  • 253,575
  • 64
  • 457
  • 625
  • Well, I only have memory leaks when I use it. Actually I know for sure it can cause memory leaks – yotamoo Sep 14 '11 at 09:29
  • I'm not sure I understand... when you call exit, your program terminates and memory is released. Can you post some code where you think you have memory leaks? – Luchian Grigore Sep 14 '11 at 09:31
  • 3
    @yotamoo What are you basing that "knowing for sure" on? Are you using some sort of tool? – Šimon Tóth Sep 14 '11 at 09:31
  • 1
    @Ahe: You may want to reread that post you linked. It's about a *possible* link being *reported* by a particular tool, because memory wasn't released when the tool thought it should be. It has nothing to do with what the OS does once the app dies. Which, BTW, is to clean up after the app, *reclaiming all its memory* and closing file handles and such. Besides all that, the OS can't leak 14 bytes or whatever via `malloc` -- it doesn't even *know* about `malloc`. It hands programs a whole page (usually 4KB) at a time, and lets them dole it out as they see fit. – cHao Sep 14 '11 at 09:44
  • So are you saying running that program multiple times will fill up your RAM? – Luchian Grigore Sep 14 '11 at 09:46
7

exit does not call the destructors of any stack based objects so if those objects have allocated any memory internally then yes that memory will be leaked.

In practice it probably doesn't matter as any likely operating system will reclaim the memory anyway. But if the destructors were supposed to do anything else you'll have a problem..

exit doesn't really mix well with c++ for this reason. You are better just allowing your program to return from main to exit, or if you need to exit from an internal function throwing an exception instead, which will cause the call stack to be unwound and therefore destructors to be called.

jcoder
  • 29,554
  • 19
  • 87
  • 130
  • 1
    "which will cause the call stack to be unwound" - provided that the exception is caught. If it isn't, then it's implementation-defined whether the stack is unwound or not. So something like `int main() { try { /* program goes here */ } catch (const ExitException &e) { return e.value; } catch (...) { return 1; } return 0; }` does the trick, where ExitException is an exception class that I've invented for the purpose of holding an exit code. Obviously logging is also helpful, and in debug mode it can be best not to catch exceptions, if the debugger does anything useful with uncaught exceptions. – Steve Jessop Sep 14 '11 at 09:44
  • Oh yes, I was assuming the exception would be caught. In practice the implementations I've used do unwind the stack even for an uncaught exception, but you shouldn't rely on undefined behavour if you can avoid it. – jcoder Sep 14 '11 at 09:48
  • @JohnB: It's not undefined behaviour. It's implementation-defined. I've seen immediate termination on throwing an uncaught exception plenty of times. – Lightness Races in Orbit Sep 15 '11 at 12:07
  • Understood - I think it's still fair to say that if you want to clean up properly on exit that calling exit() probably shouldn't be your first choice though – jcoder Sep 15 '11 at 12:38
5

The solution is to not use exit() at all. You write your program using RAII (use classes for resources management) and throw an exception when something goes wrong. Then all memory is reclaimed thanks to destructors being called.

sharptooth
  • 167,383
  • 100
  • 513
  • 979
0

You don't have a real memory leaks. When a program is terminate the OS freeing all the memory the program used.

Roee Gavirel
  • 18,955
  • 12
  • 67
  • 94
  • @ Tomalak Geret'kal - Well... Memory leak can exists for as long as the program running. for small programs it's a bad practice to not take care of that. for long-term programs such as services, kernel modules or even programs that just run for a long time like Internet-Explorer they can and most of them have memory leaks. Learn some about the OSs virtual memory mechanism to know why when a program is terminated all of his memory is freeing back to the OS. – Roee Gavirel Sep 15 '11 at 12:48
  • 1
    C++ knows nothing about virtual memory or specific OSs. A memory leak is a fault in your code where you do not give back the memory you take. If your OS happens to not care, then well done; your program is still broken, though. – Lightness Races in Orbit Sep 15 '11 at 12:51
  • @ Tomalak Geret'kal -in Windows, Linux, Unix, IOS, IPSO(Nokia), Solaris and many other OSs thing are working like that: When a application is loading the OS create a virtual memory table when it holds the mapping between the application-virtual-memory to the real memory (note: applications memory addresses are virtual address). When an application is closed the OS use the virtual memory table to reclaim all the process memory regardless if the application free it or not. – Roee Gavirel Sep 15 '11 at 12:58