What is the basic difference between Free and FreeAndNil?
Is FreeAndNil = Free + Nil?
When should I use Free and when should I use FreeAndNil?
See
And have a look at the implementation:
procedure FreeAndNil(var Obj);
var
Temp: TObject;
begin
Temp := TObject(Obj);
Pointer(Obj) := nil;
Temp.Free;
end;
Consider the following code:
procedure TForm1.FormCreate(Sender: TObject);
var
bm: TBitmap;
begin
bm := TBitmap.Create;
bm.LoadFromFile('C:\Users\Andreas Rejbrand\Documents\RAD Studio\6.0\Demos\DelphiWin32\VCLWin32\Football\up.bmp');
bm.Free;
if Assigned(bm) then
bm.SaveToFile('C:\Users\Andreas Rejbrand\Desktop\test.bmp')
else
ShowMessage('Cannot save! The bitmap does no longer exist!');
end;
This will create an error or an invalid (empty) bitmap on my desktop, because I try to use an object that has been freed. Yes, even though bm
has been freed, it is still "assigned", i.e. bm
still points to a memory adress, even though there is nothing (usable) there. To overcome this, one can set bm := nil
, as a safeguard, Then assigned(bm)
will return false, as one would want. More or less, FreeAndNil(bm)
is a shorthand for bm.Free; bm := nil
. The first statement frees all memory (and OS resources, CPU time etc. used by the object), and bm := nil
sets the "pointer" bm
to nil
, so that bm
no longer points to the place where the object used to be, but no longer is. This way you (and routines like assigned
) will not get fooled to believe that there still is a bitmap object.
Some say that you should always use FreeAndNil(foo)
rather than foo.Free
. Well, why not? The additional instruction foo := nil
will probably not take too many nanoseconds to execute, and indeed assigned(foo) = false
is a very nice property of a freed object. But then again, if you know what you are doing, and know that you will never use the foo
object again after freeing it, then you could stick to just foo.free
. Really, some would argue that in many cases (but not all), trying to use a variable of a freed object is a bug by itself. (Of course there are cases where you do this intentionally - you have an object foo
that sometimes is assigned and sometimes is not.)
Even if doesn't seem to be much different than Free, FreeAndNil will help you a lot while hunting bugs in your code.
How it saves your ass (access after free)
Just think what happens if you DON'T use FreeAndNil and then somewhere in your code you access a freed object. If you are terrible lucky, your program will immediately crash when it runs home (yes that crash is a 'good' crash). If you are a bit unlucky it will crash in customer's computer.
But this is not all. If your re unlucky, the program will not crash immediately. Or it will never crash, instead it will read or ven worst write) random chunks of memory. This is where the real pain starts!
Will it harm your program?
As others already pointed, the FreeAndNil itself is not bad. The FreeAndNil function is not broken/obsolete or something like this and it will not corrupt your code.
It is a legitimate RTL function that frees and object and then puts its pointer to NIL.
Facts vs opinions
Some will argue that relying on FreeAndNil may lead or indicate a design flaw, but they cannot justify this in any way. It is just their personal option. On the other hand, a program that cranshes randomly and undebuggingly (he he... I just create a new word) because you refused to use FreeAndNil is a fact not an opinion.
Come on... even on local variables?
I use FreeAndNil EVEN on a local variable. Using it on a local variable seems POINTLESS since the variable vanishes as soon as you exit the procedure.
Think that you may at a later date add more code at the end of the procedure, AFTER the point where you freed the object; code that will (accidentally) try to access the freed object. If the object was NIL, BABUM, instant AV (example).
A resource hog?
Some super-conservative programmers may say this simple call will waste RAM and CPU resources. I like to deliver small/fast/monolithic applications too!
But I don't think that removing using FreeAndNil will waste more than few bytes of RAM and CPU cycles. It will not make a real difference in the day-by-day life.
When you think that a single graphic resource like a TButton glyph or your program's icon can take 50-300KB (and your program can have dozens of these) it is pointless to argue about the resources "wasted' by FreeAndNil.
Gods vs programmers
Some people may say they never ever accessed a free object (basically meaning they never make mistakes) so they don't need FreeAndNil in this case. Well, I am not a robot. I do mistakes. I am not afraid to recognize it.
Pros
Mason Wheeler already points to a article that shows the 'lazy creation' method that uses FreeAndNil that we all used one day: http://tech.turbu-rpg.com/106/delphi-memory-management-made-simple
Cons
None actual (demonstrated) cons.
Allen Bauer has an article named A CASE when FreeAndNil is your enemy suggesting that using the FreeAndNil in a very particular and special case (the destructor of a visual component) could be bad. There is no code attached to the article that we can compile, only some possible scenarios where FreeAndNil might cause problems.
Allen states that FreeAndNil should be replaced with better methods. For example with FastMM.
However, this discussion demonstrates (with compilable code) that FastMM fails while FreeAndNil saves the day.
Where is the proof?
At this point I would love to have event a tiny piece of concrete/compilable code to show that FreeAndNil could do harm.
On the other hand, we de do have plenty (see links) of examples that shows how FreeAndNil can save our ass.
For those that are against FreeAndNil please enlighten us, by posting the code.
I'll answer in a different way.
Maybe, filling your object reference with nil
after freeing your object is not always a good idea.
That way, you do not have a distinction between a reference that was never used (and hence is nil
), and a reference that has been used, but should not be used in the future.
So, filling it with a magic number (similar to what the FastMM memory manager can do with the content of blocks of memory when those blocks are freed).
--jeroen
Basically, FreeAndNil sets the reference to nil and then frees the object. This marks it as unassigned. So the only reason you would need to use FreeAndNil is if your code is going to reuse the reference. If you're in a destructor or a finally block, freeing objects that you're never going to touch again, just use Free.
See Delphi Memory Management Made Simple for an example of when I did find it useful. Mghie's comment at the bottom is also worth reading.
@Bharat, the difference between Free
and FreeAndNil
is that in addition to free memory used by an object FreeAndNil
sets the object reference to nil.
you can check theses links for discussions about use Free or FreeAndNil