From: Poster Matt on
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
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
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
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
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