From: Poster Matt on 21 Feb 2010 10:53 Disclaimer: I'm returning to programming for UNIX/Linux in C after a break of 15 years and I was never a guru in the first place. This afternoon I ran into an error freeing bug in my code which took me 20 mins to debug (mainly because I was convinced I knew what the problem was but turned out to be totally wrong). The bug was simple and I'm sure it's been done in C on UNIX several million times. Pointer1 is assigned to point to the same thing as Pointer2. Pointer2 is not assigned to NULL. Later free(Pointer1) is called, and later free(Pointer2) at which point 'glibc detected... double free or corruption', cue backtrace and memory map - oops. :) My software calls a function called freeMemory() which uses free() to free the memory of various global variables, mostly char* and char**. Whenever my software terminates, whether on successful completion or with an error message for the user, freeMemory() is called. What's the point? A fraction of a second later the process will terminate freeing all the memory anyway. What do you guys do? What is the prevailing best practise concerning freeing memory before program termination? Please note: I'm not suggesting that I should skip the freeing memory process because I want to avoid my own silly double freeing mistakes or because I wish to be slack, ignore good coding practices, and just not bother to assign a no longer used pointer to NULL, that was just the catalyst to my thinking about whether I should bother running a function to free memory, just before the process will die and that will happen anyway. Your thoughts and advise will be most welcome. Cheers.
From: Eric Sosman on 21 Feb 2010 11:22 On 2/21/2010 10:53 AM, Poster Matt wrote: > Disclaimer: I'm returning to programming for UNIX/Linux in C after a > break of 15 years and I was never a guru in the first place. > > This afternoon I ran into an error freeing bug in my code which took me > 20 mins to debug (mainly because I was convinced I knew what the problem > was but turned out to be totally wrong). > > The bug was simple and I'm sure it's been done in C on UNIX several > million times. Pointer1 is assigned to point to the same thing as > Pointer2. Pointer2 is not assigned to NULL. Later free(Pointer1) is > called, and later free(Pointer2) at which point 'glibc detected... > double free or corruption', cue backtrace and memory map - oops. :) Count yourself lucky. A double-free or freeing memory not obtained from malloc() may not always be detected so neatly, and can lead to *much* more mysterious failures than the one you spent a mere twenty minutes on. > My software calls a function called freeMemory() which uses free() to > free the memory of various global variables, mostly char* and char**. > Whenever my software terminates, whether on successful completion or > with an error message for the user, freeMemory() is called. > > What's the point? A fraction of a second later the process will > terminate freeing all the memory anyway. What do you guys do? What is > the prevailing best practise concerning freeing memory before program > termination? > > Please note: I'm not suggesting that I should skip the freeing memory > process because I want to avoid my own silly double freeing mistakes or > because I wish to be slack, ignore good coding practices, and just not > bother to assign a no longer used pointer to NULL, that was just the > catalyst to my thinking about whether I should bother running a function > to free memory, just before the process will die and that will happen > anyway. "Bless you, it all depends!" -- Pitti-Sing For an ordinary user-land program in Unix (or most any other "mainstream" O/S these days), it's fine to just drop the memory on the floor and let process termination sweep it up. But ... Sometimes a program that does one thing and quits later finds itself embedded in a larger program that runs its code repeatedly, without terminating the process. You've written, say, a program that loads a big image, runs a face-recognizer, and then exits. And then you decide to adapt it to recognize the individual faces in the group photo of your college tiddlywink team: You'll load the image once (saving lots of I/O time), designate specific areas, and run the recognizer on each area. It would be a Good Thing, don't you think, if the recognizer released the gobs and gobs of memory it had claimed for its work on one face before it moved on to the next? So get out your crystal ball and try to foretell your code's future. If you just can't see any way it would ever morph into a sub-program, cut and run and let the O/S clean up. But if there are "separable subsystems" in the program, it may be worth while to have them restore the status quo ante after they've run. -- Eric Sosman esosman(a)ieee-dot-org.invalid
From: Nicolas George on 21 Feb 2010 13:28 Eric Sosman wrote in message <hlrmk2$k4g$1(a)news.eternal-september.org>: > Count yourself lucky. A double-free or freeing memory not > obtained from malloc() may not always be detected so neatly, and > can lead to *much* more mysterious failures than the one you spent > a mere twenty minutes on. To solve those kind of mysteries, knowing the magic word helps a lot: valgrind. > But ... <snip> I think you explained pretty much everything very well.
From: Poster Matt on 21 Feb 2010 15:18 Eric Sosman wrote: > Count yourself lucky. A double-free or freeing memory not > obtained from malloc() may not always be detected so neatly, and > can lead to *much* more mysterious failures than the one you spent > a mere twenty minutes on. Been there, done that, spent hours trying to find the T-Shirt. :) > "Bless you, it all depends!" -- Pitti-Sing > > For an ordinary user-land program in Unix (or most any other > "mainstream" O/S these days), it's fine to just drop the memory on > the floor and let process termination sweep it up. > > But ... > > Sometimes a program that does one thing and quits later finds > itself embedded in a larger program that runs its code repeatedly, > without terminating the process. You've written, say, a program > that loads a big image, runs a face-recognizer, and then exits. > And then you decide to adapt it to recognize the individual faces > in the group photo of your college tiddlywink team: You'll load the > image once (saving lots of I/O time), designate specific areas, and > run the recognizer on each area. It would be a Good Thing, don't > you think, if the recognizer released the gobs and gobs of memory > it had claimed for its work on one face before it moved on to > the next? > > So get out your crystal ball and try to foretell your code's > future. If you just can't see any way it would ever morph into > a sub-program, cut and run and let the O/S clean up. But if there > are "separable subsystems" in the program, it may be worth while to > have them restore the status quo ante after they've run. Sounds like good advise. I'll follow it, freeing all memory manually before termination. Thanks for taking the time to explain this to me. Regards, etc..
From: Ersek, Laszlo on 21 Feb 2010 15:16
In article <DFcgn.42662$Ym4.18042(a)text.news.virginmedia.com>, Poster Matt <postermatt(a)no_spam_for_me.org> writes: > My software calls a function called freeMemory() which uses free() to free the > memory of various global variables, mostly char* and char**. Whenever my > software terminates, whether on successful completion or with an error message > for the user, freeMemory() is called. > > What's the point? A fraction of a second later the process will terminate > freeing all the memory anyway. What do you guys do? What is the prevailing best > practise concerning freeing memory before program termination? We were just having a balanced and tranquil discussion of this exact topic in the "Experiment: functional concepts in C" c.l.c. thread. Cheers, lacos |