LinuxQuestions.org
Latest LQ Deal: Latest LQ Deals
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 06-25-2006, 07:03 AM   #1
introuble
Member
 
Registered: Apr 2004
Distribution: Debian -unstable
Posts: 700

Rep: Reputation: 31
To free() or not to free() before an exit() ?


Should you free() all alloc'd buffers before calling exit()? Why (not)?
 
Old 06-25-2006, 08:10 AM   #2
Flesym
Member
 
Registered: Aug 2005
Location: Germany
Distribution: Ubuntu, Debian
Posts: 189

Rep: Reputation: 31
You do not need to free your memory before exit. During the termination of the process the kernel also deletes the memory mappings which were associated with that process. So everything is "freed" implicit by the kernel.
 
Old 06-25-2006, 08:27 AM   #3
jlinkels
LQ Guru
 
Registered: Oct 2003
Location: Bonaire, Leeuwarden
Distribution: Debian /Jessie/Stretch/Sid, Linux Mint DE
Posts: 5,195

Rep: Reputation: 1043Reputation: 1043Reputation: 1043Reputation: 1043Reputation: 1043Reputation: 1043Reputation: 1043Reputation: 1043
I think it is better practice to free everything before your program terminates. One important advantage I can imagine is that when you run those utilities to detect memory leaks, they will return exactly zero bytes of allocated memory before exiting the program. When you leave memory allocated at the end of the program you never know whether you have a leak.

Besides, if you have a function where you allocate memory, you have to free allocated memory anyway before you return. (Unless you pass the pointer back to the caller). Main () is just another function, so why not follow this behavior?

jlinkels
 
Old 06-25-2006, 09:09 AM   #4
taylor_venable
Member
 
Registered: Jun 2005
Location: Indiana, USA
Distribution: OpenBSD, Ubuntu
Posts: 892

Rep: Reputation: 43
I agree with both points. While it's not necessary, it is good practice. Calling free() is kind of like putting curly braces around the body of "if" statements - it's not always necessary, but if you get into the habit of doing it, it will never come back to bite you.
 
Old 06-26-2006, 01:19 AM   #5
primo
Member
 
Registered: Jun 2005
Posts: 542

Rep: Reputation: 34
Quote:
Originally Posted by taylor_venable
curly braces around the body of "if" statements
It's best to put them even when you call functions. You never know if they are macros that were poorly defined.

It's always better to do a explicit free(). If you were to extend the program with atexit() handlers, the fact that some memory should/shouldn't be available may be an issue. They're called when you use the exit() call, so don't count on the OS to the work for you.
 
Old 06-26-2006, 06:46 AM   #6
Flesym
Member
 
Registered: Aug 2005
Location: Germany
Distribution: Ubuntu, Debian
Posts: 189

Rep: Reputation: 31
Quote:
Originally Posted by jlinkels
Besides, if you have a function where you allocate memory, you have to free allocated memory anyway before you return. (Unless you pass the pointer back to the caller). Main () is just another function, so why not follow this behavior?
Who said, that exit() has to be called by main()?? Consider a (common) case, where function A allocates some memory and calls function B, which then calls exit(). If you want to free all the memory which was allocated until this exit(), you would have to hold track of every block of data (on the heap) that the programm uses so far. How do you want to achieve this? -Do you pass pointers to these blocks as parameters to every function that my call exit()? Now consider, you build another function C which also allocates some memory and calls B, too. You would have to change B in such a way, that it also frees the data of function C...., an this is just a very simple case (imagine you have some complicated case of indirect recursion!)

So my advice still is to not loose yourself in such a fussy (and needless, as I mentioned in my first post) memory tracking.

Quote:
Originally Posted by primo
It's best to put them even when you call functions. You never know if they are macros that were poorly defined.
Yeah! -And don't forget to put your armor on before you go to sleep; you never know if a comet will hit you! ;-)

Last edited by Flesym; 06-26-2006 at 07:10 AM.
 
Old 06-26-2006, 07:37 AM   #7
jtshaw
Senior Member
 
Registered: Nov 2000
Location: Seattle, WA USA
Distribution: Ubuntu @ Home, RHEL @ Work
Posts: 3,892
Blog Entries: 1

Rep: Reputation: 67
Quote:
Originally Posted by Flesym
Who said, that exit() has to be called by main()?? Consider a (common) case, where function A allocates some memory and calls function B, which then calls exit(). If you want to free all the memory which was allocated until this exit(), you would have to hold track of every block of data (on the heap) that the programm uses so far. How do you want to achieve this? -Do you pass pointers to these blocks as parameters to every function that my call exit()? Now consider, you build another function C which also allocates some memory and calls B, too. You would have to change B in such a way, that it also frees the data of function C...., an this is just a very simple case (imagine you have some complicated case of indirect recursion!)
With the exception of the case where you exit based on a signal handler well designed program flow should allow you to always free the memory you allocate at some point. Not being careful with this when you design software in C is how you end up with nasty memory leaks.

Anyway.. for my answer to the original question... it is always best where possible to free memory you allocate. You never know when you might end up coming back to your code later and incorporating it into a bigger program and forget you didn't do all your memory accounting in the past.

Last edited by jtshaw; 06-26-2006 at 07:39 AM.
 
Old 06-26-2006, 06:55 PM   #8
jlinkels
LQ Guru
 
Registered: Oct 2003
Location: Bonaire, Leeuwarden
Distribution: Debian /Jessie/Stretch/Sid, Linux Mint DE
Posts: 5,195

Rep: Reputation: 1043Reputation: 1043Reputation: 1043Reputation: 1043Reputation: 1043Reputation: 1043Reputation: 1043Reputation: 1043
Writing programs which exit in nested functions is generally considered as bad programming practice. You should leave functions at the return statement, not somewhere in the middle.

You are right that if your program receives a SIGHUP, it is killed in the middle, and you have to leave cleanup to the OS. However, this is not normal practice. The program ought to be WRITTEN such that it leaves nicely at the end of main. And has cleaned up all the garbage.

If you make it a practice to leave your program somewhere in the middle, leaving it to the OS to clean up your memory allocations, and you ever have to find a memory leak, I wish you lots of good luck.

BTW, Primo might overdo it with curly braces around everything, but this can be considered defense or robust programming. Better check twice, we all make errors, others make (more) errors, the unexpected happens. That is why it is possible to make a program in plain old C behave like it is bug free. And that is why most GUI based programs, written in an OO language, with zillions of things assumed and not checked or double armed starts to behave oddly sooner or later.

jlinkels
 
Old 06-26-2006, 07:35 PM   #9
tuxdev
Senior Member
 
Registered: Jul 2005
Distribution: Slackware
Posts: 2,012

Rep: Reputation: 115Reputation: 115
For a shell programming assignment, calling exit() within the function that handled all of my ridiculously simple builtins in order to (obviously) implement the builtin 'exit' was the simplest thing to do that does the right thing. The major question I would have is if doing a free of all your memory yourself is going to be slower than letting the kernel do it for you. Maybe the best option is to write the code within a #ifndef NDEBUG block. It might help to apply RAII to C code as best as you can.
 
Old 06-27-2006, 03:10 AM   #10
Flesym
Member
 
Registered: Aug 2005
Location: Germany
Distribution: Ubuntu, Debian
Posts: 189

Rep: Reputation: 31
Quote:
Originally Posted by jlinkels
You are right that if your program receives a SIGHUP, it is killed in the middle, and you have to leave cleanup to the OS. However, this is not normal practice. The program ought to be WRITTEN such that it leaves nicely at the end of main. And has cleaned up all the garbage.
I agree, that it's a much better style to let the process end itself after returning of main, but then you don't have to call exit(), which was made to terminate your program somewhere in the middle (and this is was the question was about). Surely, you can free everything by hand, but I think it isn't worth a thought (of course, only before and exit()!) and unless it really is the most trivial case, I don't see any significant advantages. The argument of finding memory leaks isn't that strong; actually I find it quite easy to identify and classify them with the help of modern tools. And because this analysis have to be done in any case (as you said: "We all make errors"), you don't loose much time.

And yes, defensive programming is a very good thing! But I think even here are limits; if you convulsive try to hold your defense in any possible case, you may forget what you actually are fighting for. A defensive pattern in programming is only useful, if it avoids hard detectable (thus time consuming) bugs and errors which may relatively often occur. Your brace-if was a good example for this. But the brace-function-call to avoid bad macros.... First I don't use a macro unless I don't know what it does and second I never (in almost 15 years of programming experience) came across such a macro that would make i possible to put it between braces (at least I don't remember). -Surely everyone can construct such one, but fact is, that they must be very, very rare in the real world and putting every function call between braces is definitely not worth the effort - maybe it's defensive but it's no good style!

My conclusions of this:
Yes I agree, that a program flow should be clear designed and it is desirable to be able to free memory before an exit(), but the reality shows, that it is quite easy to run into a situation where this is just not given; and in such a situation you don't need to care much about it. And yes, defensive programming is a must today, but while doing so you should have the feeling, that the advantages you gain are bigger then the costs you pay.
 
Old 06-27-2006, 03:58 AM   #11
primo
Member
 
Registered: Jun 2005
Posts: 542

Rep: Reputation: 34
Quote:
Originally Posted by Flesym
Your brace-if was a good example for this. But the brace-function-call to avoid bad macros.... First I don't use a macro unless I don't know what it does and second I never (in almost 15 years of programming experience) came across such a macro that would make i possible to put it between braces (at least I don't remember). -Surely everyone can construct such one, but fact is, that they must be very, very rare in the real world and putting every function call between braces is definitely not worth the effort - maybe it's defensive but it's no good style!
Oh my... I wasn't talking about putting braces around every function call. I put braces around if's and else's when there's a function call. Braces are never curly. The way you indent them may be.

Quote:
My conclusions of this:
Yes I agree, that a program flow should be clear designed and it is desirable to be able to free memory before an exit(), but the reality shows, that it is quite easy to run into a situation where this is just not given; and in such a situation you don't need to care much about it. And yes, defensive programming is a must today, but while doing so you should have the feeling, that the advantages you gain are bigger then the costs you pay.
Toy programs aren't supposed to waste your time. But in other projects that may be later extended, the time you think you saved you will lose twice. It's neither good style nor proper design to leave it to the OS. I guess I'm wasting my time stating the obvious.
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
Question about malloc - free and exit prog. pentalive Programming 6 05-08-2006 09:55 PM
Error : CHILD : exit on signal (11) in free radius AZIMBD03 Red Hat 0 02-18-2006 02:44 AM
LXer: The Office-free life: Surviving on free Web-based services alone LXer Syndicated Linux News 0 12-22-2005 05:01 AM
Free Software, Free Society: Selected Essays of Richard M. Stallman irfanhab Linux - General 1 11-09-2004 06:22 AM
Free, free,FREE=? no money, = Freedom? murshed Linux - Newbie 8 01-20-2003 07:01 AM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 05:27 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration