- Free allocated memory on exit?
- Posted by Bob Masta on June 30th, 2004
Hello, all.
I have been operating under the concept that one
should always free any memory one allocates.
But it occurs to me that Windows must surely
free all allocated memory when the program terminates.
True? If so, is there any reason I need to free
it in my exit clean-up code?
Thanks!
Bob Masta
dqatechATdaqartaDOTcom
D A Q A R T A
Data AcQuisition And Real-Time Analysis
www.daqarta.com
- Posted by Allan Bruce on June 30th, 2004
"Bob Masta" <NoSpam@daqarta.com> wrote in message
news:40e2ae09.1194143@news.itd.umich.edu...
I am not sure about this but here is what I think. Yes, Windows does clean
up the memory of your application after you, however it may take windows
time to search through the allocated memory and handles to get rid of so you
are creating a lot of work for windows to do it by itself. If you clean up
after yourself, your application will quit gracefully and efficiently.
Of course, I could be totally wrong! but this is the reason I always try to
ensure that I clean up myself.
(Is it possible that the program may also hang somewhere before completely
terminating, therefore windows wont do any clean up? I guess this may
happen before you do the clean up, but its an interesting thought)
Allan
- Posted by Stephen Kellett on June 30th, 2004
Yes.
Yes.
Yes. If you don't you will find it very hard (*) to identify memory
leaks that occur in your application, as they will be masked by the
noise of the memory that you'd normally clean up during application
shutdown.
(*) Thats a serious understatement for anything other than a trivial
application.
Stephen
--
Stephen Kellett
Object Media Limited http://www.objmedia.demon.co.uk
RSI Information: http://www.objmedia.demon.co.uk/rsi.html
- Posted by Gernot Frisch on June 30th, 2004
void Func()
{
long* a = new long[1024];
}
while(true)
{
Func();
}
.... do you really want to make code like this happen after a few years
work on a huge project? Do clean up. If you don't want to, there's
garbage collector classes that will do for you. Use one of them,
although it's not very efficient.
--
-Gernot
int main(int argc, char** argv) {printf
("%silto%c%cf%cgl%ssic%ccom%c", "ma", 58, 'g', 64, "ba", 46, 10);}
________________________________________
Looking for a good game? Do it yourself!
GLBasic - you can do
www.GLBasic.com
- Posted by Scott Moore on June 30th, 2004
Bob Masta wrote:
The heap memory from Windows is actually allocated from virtual
memory pages. So to be technically correct, the memory may not
be freed even if you *do* call free() for it. It simply remains
as part of a page in your working set.
Is it a good idea ? Of course, its a clean program issue. Even
better would be a way to verify that you have completely freed
up all allocations, which would go a long way towards telling
you that you don't have memory leaks.
--
Samiam is Scott A. Moore
Personal web site: http:/www.moorecad.com/scott
My electronics engineering consulting site: http://www.moorecad.com
ISO 7185 Standard Pascal web site: http://www.moorecad.com/standardpascal
Classic Basic Games web site: http://www.moorecad.com/classicbasic
The IP Pascal web site, a high performance, highly portable ISO 7185 Pascal
compiler system: http://www.moorecad.com/ippas
Being right is more powerfull than large corporations or governments.
The right argument may not be pervasive, but the facts eventually are.
- Posted by Norm Dresner on June 30th, 2004
"Bob Masta" <NoSpam@daqarta.com> wrote in message
news:40e2ae09.1194143@news.itd.umich.edu...
As others have said, all memory allocated by your program is automatically
freed simply by wiping away the virtual memory map -- BUT -- resources may
not be freed. A Brush is an example of something that you have to free
explicitly because it's not your memory but system memory.
Norm
- Posted by Craig Kelly on June 30th, 2004
"Bob Masta" :
In C++ and other languages with destructors (that are deterministic), "when"
a resource is freed can be just as important as "if".
In addition, I have always been of the opinion that you should always clean
up after yourself (even in a garbage-collected language). That way someone
reading the code knows _where_ you meant to free the resource (and that you
thought about it!). And readability is always a good thing.
IMHO, you can safely ignore freeing resources in certain situations (e.g. a
chunk of memory that exists for the life of the program: the OS will free it
for you when your process ends), but you can also "safely" use nothing but
global variables. Both have the same impact: reducing readability,
increasing maintenance time, and increasing the bug count (or at least the
probability of a higher bug count).
<gratuitous comment>
This is why I hate COBOL. 
</gratuitous comment>
Craig
- Posted by Severian on July 1st, 2004
On Wed, 30 Jun 2004 18:19:53 GMT, "Norm Dresner" <ndrez@att.net>
wrote:
In real 32-bit Windows (NT/2k/XP/2k3), all system resources are freed.
It's only the old hybrid 16/32-bit POS systems that didn't handle this
properly.
That doesn't mean you can blithely leak resources; there are still
overall system limits and process limits.
--
Sev
- Posted by Gil Hamilton on July 1st, 2004
"Allan Bruce" <allanmb@TAKEAWAYf2s.com> wrote in message news:<cbucu1$nu0$1@news.freedom2surf.net>...
Yes, you are totally wrong. :-)
As others have already pointed out, calling "free" doesn't necessarily
release any memory acquired by the process. And any handles should be
released by the OS when your process goes away (at least, as another
poster pointed out, on NT-derived versions of Windows). This is more
an issue of writing clean code than worrying about "creating a lot of
work for windows". Windows has to do that work anyway.
(I don't want to discourage anyone from writing code that cleans up
after itself as there are many other good reasons to clean up. But
it's also good for programmers to understand how the OS works so....
Strictly speaking, it's more efficient to let the kernel clean up.
Consider, for example, closing of handles: Each CloseHandle() call
translates into a separate system call that involves some overhead
[transition to supervisor mode, saving registers, validating
arguments, etc.]. If you simply call ExitProcess, Windows can quickly
run through the list of handles associated with your process avoiding
the context switches and other overhead.)
- GH
- Posted by Alex Blekhman on July 1st, 2004
<offtopic = 100%>
As many already posted here by abandoning acquired resources you won't
be killed (at least immediately). However, we all do this irrational
thing for some strange reason. The same reason we wipe our asses and
wash our hands and make our beds by morning. There's no apparent
reason to make a bed at morning, it will be total mess by evening
again. And in very short period all sheets will be in laundry anyway.
Also, there's no rational reason to cut our hair and nails: Mother
Earth, our ultimate hosting system, will reclaim all our organic
resources back someday. We can't escape it and final balance will be
restored. However, we keep doing these strange movements. May be
because it's called civilization?
:-)
</offtopic>
- Posted by Bob Masta on July 3rd, 2004
Many thanks to everyone who replied.
However, I'm a little confused: The
consensus seems to be that Windows
does indeed free all allocated memory in exit,
but that I should do it myself anyway, Setting
aside the issue of whether this is really better
programming practice, I really don't understand
the comments about memory leaks. If Windows
frees it anyway, then that would seem to eliminate
the potential for any leaks due to memory I had
allocated; freeing it myself would be redundant.
And whether Windows frees it or I free it, it's not
there as a background "noise" to disguise any
system resource leaks.
In case it makes any difference, I am talking about
memory arrays that last essentially the life of the
program. My inclination is that if Windows frees
this, I should let it do so. Adding redundant code
isn't going to improve the program, or its readability,
and certainly not its maintainability. So why do it?
Bob Masta
dqatechATdaqartaDOTcom
D A Q A R T A
Data AcQuisition And Real-Time Analysis
www.daqarta.com
- Posted by Scott McPhillips [MVP] on July 3rd, 2004
Bob Masta wrote:
A very good reason to free the memory is so that when the program is
tested, by you or others, it will show zero memory leaks. If testing
shows memory leaks then further analysis and investigation is required.
So for 2 or 3 lines of easy code you help diagnostic tools give the
program a clean bill of health. That is a definite contribution to
maintainability.
--
Scott McPhillips [VC++ MVP]
- Posted by Stephen Kellett on July 3rd, 2004
Bob,
You are wrong.
Consider this.
App starts, during initialisation, allocates some arrays.
Stage 1
for(i = 0;i < 1000; i++)
{
array[i] = new char * [bigSize];
}
whilst app works allocates many objects and also leaks some objects
Stage 2
for(i = 0;i < 5000; i++)
{
leakyArray[i] = new char * [leakySize];
}
app quits, during shutdown you free your long-lifetime arrays.
Stage 3
for(i = 0;i < 1000; i++)
{
delete [] array[i];
}
MFC outputs that you've 5000 objects of leakySize. Or your leak
detection tool indicates this to you.
Thats a trivial example. If you forget stage 3 then you have your
"benign" leaks clouding the genuine leak report for the objects leaked
in stage 2.
Now consider that leak 2 is not 5000 objects, but a random number of
leaked objects from anywhere in your app where you've failed to cleanup.
Even worse if they are allocated in a loop, or based on user input/input
from a remote source. It is so much harder to identify these if you have
"benign" / intended leaks in your app. If you just took the effort to
write Stage 3 then you'd be easily able to identify those caused in
stage 2 (the lifetime of your app).
The sad thing (for me) is that it would have taken you less time to
write Stage 3 than you've spent on this exercise asking the newsgroup
what to do. This in itself would have been a useful exercise for
yourself in that it would have improved the maintainability of your
application.
Memory leaks sometimes have the strange side-effect of hiding more
serious programming errors in your code (such as buffer overruns or
accessing pointers that should be NULL, but are not because they haven't
been freed - this really means that pointer is working with bad data).
I've been fixing other peoples memory related errors since 1990. Please
fix this issue with your app. It will reduce your maintenance costs,
long term, but a large, but unspecifiable amount (because I can't
predict how much time you will waste if you don't fix these errors).
Stephen
--
Stephen Kellett
Object Media Limited http://www.objmedia.demon.co.uk
RSI Information: http://www.objmedia.demon.co.uk/rsi.html
- Posted by Stephen Kellett on July 3rd, 2004
And, if you are using a software tool that reports memory leaks and also
supports regression testing you can add the software tool to your
regression testing suite so that you can detect new memory leaks on your
overnight build/regression test.
Just such a tool is Memory Validator.
http://www.softwareverify.com
....and yes, the regression testing facilities were added because they
were needed for addition to a regression test suite that could run for
anything between 40 minutes and 7 days depending on the length of the
test.
Stephen
--
Stephen Kellett
Object Media Limited http://www.objmedia.demon.co.uk
RSI Information: http://www.objmedia.demon.co.uk/rsi.html
- Posted by Stephen Kellett on July 4th, 2004
In message <3r$ynHBaEz5AFwH1@objmedia.demon.co.uk>, Stephen Kellett
<snail@objmedia.demon.co.uk> writes
Re-reading this, the above may sound high-handed/patronising. I
apologize if it comes across as that way, as it wasn't intended.
Stephen
--
Stephen Kellett
Object Media Limited http://www.objmedia.demon.co.uk
RSI Information: http://www.objmedia.demon.co.uk/rsi.html
- Posted by Bob Masta on July 4th, 2004
On Sun, 4 Jul 2004 12:12:26 +0100, Stephen Kellett
<snail@objmedia.demon.co.uk> wrote:
Stephen, I appreciate the time you have taken to respond.
In my original post I said:
allocate, just trying to understand the rationale for it
if Windows is doing it for me anyway. I hadn't considered
the quirks of debugger operation; seems odd that the
debugger can't figure out what memory Windows is
going to free on exit, and not have a problem with that.
I should note that I am talking about explicit GlobalAlloc
API calls for my allocations, if that makes any difference.
I am having a hard time understanding what can and can
not cause a memory leak, but it sounds like GlobalAlloc
can't do it, if its memory is automatically freed on exit.
Thanks again for your help!
Bob Masta
dqatechATdaqartaDOTcom
D A Q A R T A
Data AcQuisition And Real-Time Analysis
www.daqarta.com
- Posted by Tim Robinson on July 4th, 2004
Bob Masta wrote:
Just to reiterate:
-- Windows reclaims all memory when your program exits. You can't lose
memory.
-- Windows will not reclaim memory at runtime. You must free it yourself.
-- You should be using some sort of memory tracking software. You can detect
leaks by looking at all the memory which is still allocated when your
program exits.
-- If you don't free all of your memory, how do you know which are
legitimate leaks and which are not?
In other words, given a memory leak report, how do you know which memory is
leaked once per second (say) and which is leaked only once in the lifetime
of the program? If you free all the memory you allocate (a special case of
"release all resources you acquire"), you won't need to guess: all blocks
still allocated when your program exits are sources of leaks.
By the way, why are you using GlobalAlloc? If you use malloc/free or
new/delete, you get free leak tracking. Or you could use one of Mr.
Kellett's tools
.
--
Tim Robinson (MVP, Windows SDK)
http://mobius.sourceforge.net/
- Posted by Stephen Kellett on July 4th, 2004
In message <40e7f98c.1639643@news.itd.umich.edu>, Bob Masta
<NoSpam@daqarta.com> writes
Treat all memory allocators the same. If you re-read my "consider this"
argument and replace "new" with GlobalAlloc and "delete" with GlobalFree
the argument is identical, except the CRT/MFC won't warn you when you
leak, but a memory analysis tool, such as Memory Validator, will tell
you about the leaks if you configure it to monitor GlobalAlloc and
related allocators.
A memory leak is a memory leak regardless of which allocator family it
comes from. Don't think you can pay attention to one and ignore the
others. You cannot.
Stephen
--
Stephen Kellett
Object Media Limited http://www.objmedia.demon.co.uk
RSI Information: http://www.objmedia.demon.co.uk/rsi.html
- Posted by Scott McPhillips [MVP] on July 4th, 2004
Bob Masta wrote:
The rationale for it has nothing to do with releasing memory when your
program exits. Windows will reclaim the memory.
The real problem is that if you leak memory while executing then after X
hours or X days your program will run out of memory. Program exit time
is merely a convenient point to check for such latent problems. The
fact that Windows recovers the memory upon exit does not cure a
program's long-term unreliability.
--
Scott McPhillips [VC++ MVP]
- Posted by Bob Masta on July 5th, 2004
On Sun, 4 Jul 2004 14:11:30 +0100, "Tim Robinson"
<tim.at.gaat.freeserve.co.uk@invalid.com> wrote:
I'm using GlobalAlloc because I'm coding in MASM32.
However, since most of the allocations in question are essentially
static, I am going to avoid this issue entirely by putting those in
the uninitialized data section (designated as ".data?"and generally
known as BSS in the source). Those take up no space in the
executable file until loaded, and otherwise behave just like ordinary
data.
Any allocations I make at run time will continue to be freed
explicitly on exit, as at present.
And I will have to read up on leak testing. Any recommendations
on basic theory or tutorials, hopefully on the Web?
Thanks!
Bob Masta
dqatechATdaqartaDOTcom
D A Q A R T A
Data AcQuisition And Real-Time Analysis
www.daqarta.com