Should I free memory before exit?

16,517

Solution 1

It depends on the OS. Best practice I'd say you should explicitly free it. It also makes using tools like valgrind a PITA if you have memory not freed all over the place and I cannot tell what's good and bad etc.

If on an OS that explicitly frees memory you still have the problem of other resources. As your app starts to grow and pull in third party libraries you can get resource leaks. Imagine I've written a library that asks that you call close on a handler. This handler happens to be backed by temporary files that doesn't get deleted unless you call close. Or I've detached processes that are running in the background that I'm managing using signals or some other resource that you're unaware of.

Solution 2

This is actually a really hard, imponderable question.

Pro (in favor of freeing everything before exit):

  • no bugs or memory leaks later if code is rearranged
  • no false positives from valgrind or memory leak checker
  • no memory leaks if you're running under a buggy OS, or no OS at all

Con (just exit, don't worry about freeing everything):

  • freeing everything can be a lot of work
  • freeing everything can introduce bugs and crashes
  • your OS really, really ought to reclaim all resources for you when you exit

And, one more point (not sure if it's a pro or a con): on the majority of systems, calling free does not return memory to the Operating System (only exiting does that).

In the end, you will have to decide which of these pros and cons matters most for you. Different programmers on different projects under different circumstances will reach different conclusions; there is no one-size-fits-all answer here.

See also this previous Stack Overflow question. See also question 7.24 in the C FAQ list.

Solution 3

You should always free allocated memory before you exit. As already mentioned in other answers, this will minimize warnings from static- or dynamic analysis tools etc.

But the real reason why you should always do this, is because freeing often exposes dormant run-time bugs in your application.

If you have a bug somewhere that causes memory corruption or changes pointer addresses, that bug may stay silent and dormant. Until you change something completely unrelated to the bug and thereby shuffle around the memory layout. Then suddenly you get a crash and you'll have no idea why, because the bug isn't even located in the code you just added.

By freeing the memory, you provoke such bugs to surface. Because if there is anything wrong with the heap or with the pointers pointing at the heap, then you will often get a crash at the point where you call free(). Which means that you have a severe bug somewhere, that you need to find before shipping the program.

Solution 4

You don't need to free memory before program termination. Terminating the program in any way causes all memory to be deallocated automatically.

Share:
16,517
Lucfia
Author by

Lucfia

Updated on June 12, 2022

Comments

  • Lucfia
    Lucfia about 2 years

    Should I free all my mallocated memory when I am exiting program in the due of error?

    something = (char**) malloc (x * sizeof(char*));
    for (i = 0; i < x; i++)
        something[i] = (char*) malloc (y + 1);
    
    ...
    
    if (anything == NULL) {
       printf("Your input is wrong!");
       // should I free memory of every mallocated entity now?
       exit(1);
    } 
    else {
       // work with mallocated entities
       ...
       free(something); // it must be here
       system("pause);
    }
    
  • EOF
    EOF about 8 years
    In a hosted environment with proper process isolation, and ignoring things like shared memory...
  • CodeMouse92
    CodeMouse92 about 8 years
    I agree with this answer on a technical level, but not on a practical level. I agree with Eugene and Kevin in the question comments: it's better to clean up after oneself anyway. Otherwise, a later code rewrite could sufficiently rearrange things to trigger UBs that wouldn't have been present before.
  • KevinDTimm
    KevinDTimm about 8 years
    I want to down vote this answer as these are the kinds of things that eventually bite us. I didn't, but I want to.
  • fuz
    fuz about 8 years
    @JasonMc92 I disagree. On error exit, it's often very hard or impossible to correctly clean up all the memory as data structures may be corrupted. Attempting to clean things up is a futile endeavour.
  • CodeMouse92
    CodeMouse92 about 8 years
    @FUZxxl, yes, there are situations where one can't necessarily clean up, but that doesn't leave an excuse for intentionally skipping clean-up that one can clean, for the reason I cited above. Just because you can't scrub behind the fridge doesn't mean you don't mop the floor.
  • Martin James
    Martin James about 8 years
    If a program wishes to exit because it has detected a problem that may have impacted memory-management, trying to free stuff will just make things worse:( On non-trivial OS, let the OS do it - it's really, really good at it, much, much better than user code.
  • fuz
    fuz about 8 years
    Which systems cannot free memory after program termination?
  • Martin James
    Martin James about 8 years
    @JasonMc92 excuse? It's a very good reason indeed. Unless there is an overriding reason to do so, it's pointless effort at best, slower on average and dangerous at worst to try and duplicate in user code what the OS can easily do on its own.
  • fuz
    fuz about 8 years
    @JasonMc92 Why clean the floor if you tear down the house? There is zero purpose in freeing memory right before terminating the program. Terminating the program frees all memory anyway, freeing it manually beforehand is redundant and useless.
  • Martin James
    Martin James about 8 years
    ..and may be impossible. If the allocation is buried in an opaque library, you're stuft. Also, unlike the OS, user code is unable to guarantee stopping all process threads in any state before attempting to free memory. If a thread is CPU-looping, you cannot stop it with user code. The OS can, and does.
  • Harry
    Harry about 8 years
  • Martin James
    Martin James about 8 years
    The way to handle temp files is to delete them on runup, not on shutdown. Power can fail at any time, and apps that rely absoultely on a shutdown procedure will be in trouble.
  • fuz
    fuz about 8 years
    @Harry If you are programming for such a system, you know this and don't ask this kind of question on Stack Overflow.
  • CodeMouse92
    CodeMouse92 about 8 years
    I think what I'm saying is this: we need to default to manual clean up, and make a conscious decision to leave it to the OS when appropriate. If we default to "let the OS to it" and have to make a conscious decision to clean up ourselves, we are more likely to "forget" things that lead to dangling pointers and the like (especially during code rewriting), and thereby yield UBs. The decision to not clean up manually needs to be an educated intentional choice, as I'm sure it is for ya'll by habit. Less experienced coders need to form that habit.
  • CodeMouse92
    CodeMouse92 about 8 years
    The way to form that habit, of course, is to habitually plan for manual cleanup when possible, and when they realize it will be difficult/impractical/dangerous, making the conscious decision of "I had better leave this to the operating system to clean up." With the opposite habit, many a newbie coder will decide "I don't need to free my malloc. The OS will do it!" and fail to notice that they're asking for a swarm of nasal demons five lines later.
  • CodeMouse92
    CodeMouse92 about 8 years
    Well said! Restating a comment I made below: if you're a newbie, in general, make "free it manually" the habitual instinct (less dangerous habit), and make "leave it to the OS" be a conscious, informed, case-by-case decision. The decision-making process for that will become instinct over time. Otherwise, you'll habitually forget to free your mallocs and clean up your dangling pointers, and you're subsequently signing up for surprise UBs the next time you change your code in such a way that failing to free the memory now matters.
  • CodeMouse92
    CodeMouse92 about 8 years
    Absolutely. The question is, do you want the person to learn that a stove light indicates the burner is hot by letting them touch it, or by discovering that they can't boil water when the light's off? Oversimplified example, of course. In that scenario, you tell them, but the basic idea is: do they learn from getting injured or from taking the long, non-injurious way around? Forming the habit the way I described leaves them to discover things by the unintentional scenic route when there was a shorter way (always a good learning opportunity), instead of by self-inflected UB injury.
  • fuz
    fuz about 8 years
    @JasonMc92 If you don't understand the importance of proper memory management by getting burned by not doing it right at first, you will never understand the importance and write weird code.
  • CodeMouse92
    CodeMouse92 about 8 years
    @FUZxxl really? That's not how I learned about proper memory management. I learned by following the warning "free your mallocs!" the first time, and discovering the rarer cases where freeing them weren't possible/practical down the road after chasing my tail for a bit. I prefer that way of learning - I picked up some cool knowledge while I chased my tail, and it was less stressful than getting a glut of UBs. (I might add, mine is typically Valgrind pure on the first shot.)
  • CodeMouse92
    CodeMouse92 about 8 years
    I might add, this Q&A backs up my point. By and large, freeing manually is usually an issue of stability (short- and long-term), while not freeing manually is usually an issue of performance, and we all know the adage: "Premature optimization is the root of all evil." (-Donald Knuth). Free by habit, decide not to by choice.
  • Martin James
    Martin James about 8 years
    Unfortunately, many college/uni courses are taught by people who have never actually delivered anything that works:(
  • Martin James
    Martin James about 8 years
    Unnecessary and unwarranted explicit freeing is premature stoptimization.
  • Martin James
    Martin James about 8 years
    @JasonMc92 while that sounds nice, it is building extra unreliablity into today's code. Explicitly freeing memory at app termination is not free, not safe and not always possible. It's usually unnecessary extra code that needs to be tested and debugged, over, and over again, on all OS versions. It's uni cargo-cult mantras like 'you must always explicitly free before terminating' that result in the many apps we have both used that will not shut down cleanly and quickly:(
  • CodeMouse92
    CodeMouse92 about 8 years
    As I said on the other (longer) comment chain: the link in the answer backs up my point. By and large, freeing manually (overall, not just at program end) is usually an issue of stability (short- and long-term), while not freeing manually is usually an issue of performance, and we all know the adage: "Premature optimization is the root of all evil." (-Donald Knuth). Free by habit, decide not to by choice, not to ensure OS gets the memory back, but to prevent errors when we refactor code later. Beyond that, we have a "holy war" and had probably best agree to disagree.
  • Per Lundberg
    Per Lundberg over 6 years
    This answer is good because it goes beyond the idea of just debating the "holy war" part of this subject. Thanks @Lundin, valuable points!
  • vpalmu
    vpalmu almost 6 years
    I found running under no OS being the ultimate no memory leaks. When your exit chainloads the next program it comes up just as yours did and sees all the memory in the computer as randomly initialized free memory.
  • Sled
    Sled over 5 years
    @MartinJames do both? Leave no mess behind, boyscott principle and all
  • klutt
    klutt almost 4 years
    You could argue that if it's a lot of work to free, then the program is poorly designed.