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
delphibasics-FreeAndNil
docwiki.embarcadero-FreeAndNil
pages-freeandnil [Broken]
eurekalog-freeandnil
blogs.embarcadero (via Wayback Machine)
...
And have a look at the implementation:
procedure FreeAndNil(var Obj);
var
Temp: TObject;
begin
Temp := TObject(Obj);
Pointer(Obj) := nil;
Temp.Free;
end;
Examples
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.
Discussion
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.)
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.
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
#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
A case against FreeAndNil
Don’t abuse FreeAndNil anymore
JWSCL and FreeAndNil
JWSCL and FreeAndNil Second Attempt
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
No actual/solid evidence.
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 even ONE SINGLE tiny piece of concrete/compilable code to show that FreeAndNil could do harm.
On the other hand, we 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 some compilable code.
Related
Delphi doesn't have a garbage collector, so coming from a Java background this is a real pain in the neck.
Usually, to destroy some memory I won't use anymore I'd use:
if (SomeMemory <> nil) then
SomeMemory.Free
What would happen if I don't check for nil before deleting?
Additionally, why someone would want to deal with all this "garbage collecting" by himself? Why among all the compiling options Delphi has, there is no Garbage Collector = true
The code for TObject.Free looks like this :
procedure TObject.Free;
begin
if Self <> nil then
Destroy;
end;
So there is no need to check for nil. You can still get into trouble if you try to free an uninitialized variable, however, as this will result in an AV. Checking for nil (or Assigned) obviously doesn't help you there either. The compiler will warn you if you try to do this, however.
To answer your second question
Why among all the compiling options Delphi has, there is no Garbage Collector = true
The simple answer is that Delphi does not have such a garbage collector. Certain managed types (like strings, dynamic arrays, etc) implement compiler-managed automatic reference counting, and those objects are automatically freed when their reference counts fall to zero. For all other unmanaged objects it is the responsibility of the developer to appropriately clean up object instances when they are no longer needed.
It's not a question of wanting to have to manage your application's memory, it's just a matter of course that you need to.
Checking for nil before Free is redundant. If the reference is nil, then it's already safe to call Free on it. If the reference isn't nil, then the safety of calling Free on it is unchanged and depends entirely on whether the variable contains a valid reference.
For example:
SomeMemory := nil;
SomeMemory.Free; // This is safe.
SomeMemory := TObject.Create;
SomeMemory.Free; // This is safe
Assert(SomeMemory <> nil);
SomeMemory.Free; // This is an error (EInvalidOperation)
In the first block, we don't check whether the variable is null, and yet the call to Free is perfectly safe. It does nothing. In the second block, we see that the variable remains non-null, but calling Free on it yields an exception.
There is a pretty straight-forward way in Delphi to have (something like) garbage collection: use interface pointers. By using variables of a type ultimately derived from IInterface (or IUnknown which is basically the same thing), Delphi will keep close count of the references, and free/destroy/release the instance when the last reference is removed. Using interface pointers, apart from instance creation and a few other things, is almost identical to using object references.
In Nick Hodges' recent work Coding In Delphi, there's quite a bit on this programming technique, and its relations to abstraction, generics, unit testing and dependency injection.
Also new versions of Delphi for other platforms will have ARC (automatic reference counting) on object references as well, operating like interfaces do now. (Obsoleting the Free method, but that's another story.)
You can always consult the documentation in order to answer such a question. Here it is, with my emphasis:
Use Free to destroy an object. Free automatically calls the destructor if the object reference is not nil. Any object instantiated at run time that does not have an owner should be destroyed by a call to Free, so that it can be properly disposed of and its memory released. Unlike Destroy, Free is successful even if the object is nil; if the object was never initialized, Free would not result in an error.
Find a more complete discussion of the issue here: Why should I not use "if Assigned()" before using or freeing things?
Suppose an application with some forms and only one data module are created at start.
In the DM1.OnCreate event, a TStringList is created to be used at runtime.
We know that when the application is being terminated, all things will be destroyed and memory will automatically freed. Freeing something can take some time, and so is not always advised to worry about memory leaks on shutdown. See for example this answer from Barry Kelly or this post from Raymond Chen.
Beside that, FastMM reports the memory leak if I don't add TStringList.Free to DM1.OnDestroy. This turns out to be a problem when searching for any other memory leaks that I should really worry about.
So basically I am asking if/why/when I should free object instances that will be freed by application or OS (Windows in this specific case). Is there any other valid case that is not when hunting for memory leaks?
NOTE: In this specific case, the data module is not created or recreated more times. There will not be any memory leak at all, besides the one. The data module scrap source:
unit UDM1;
interface
uses SysUtils, Classes, ...;
type
TDM1 = class(TDataModule)
procedure DataModuleCreate(Sender: TObject);
procedure DataModuleDestroy(Sender: TObject);
procedure DoStuffWithStringList1(Sender: TObject);
private
internalStL: TStringList;
end;
var
DM1: TDM1;
implementation
procedure TDMInterfacePAFECF.DataModuleCreate(Sender: TObject);
begin
internalStL := TStringList.Create();
end;
procedure TDMInterfacePAFECF.DataModuleDestroy(Sender: TObject);
begin
internalStL.Free; //<-- IS THIS NECESSARY OR ADVISED?
end;
procedure DoStuffWithStringList(Sender: TObject);
begin
//Place some code using internalStL here...
end;
For the same reason I strongly advocates (understatement) for not leaving any Compiler Hint or Warning in a project, clean after yourself and DO NOT LEAVE A REPORTED MEMORY LEAK!
EVER!
Now, that does not necessarily means that you have to Free everything in the Destructor of your DataModule if you have a strong case for not doing it, but in that case, you need to register your Memory Leak so that it will not be reported. (And put there a very visible comment to justify and explain why)
But consider the fact that you may leave this project and a year from now, someone else is maintaining it and has a new business requirement to create multiple DataModules... Chances are that if they do not know the inside of your code well enough, they will trust your code to be clean and problems are likely to follow.
So I would strongly advise against not freeing unless in a very special and expected and documented case...
PS: Seen that and had to mop up the memory dripping all over the place so many times that I even did some CodeRage sessions on fighting memory leaks...
Updayte: Here's the link to download that CodeRage session...
My answer can be considered philosophical, but the main reason is that any action (or absence of it) has consequences. I thought about your example and probably other examples and I see one good reason to free the object. Every time I think I can ignore freeing object increases the probability of not doing this in other, maybe more serious situation. Another example is a habit of doing "try finally end" everywhere something is allocated or freed. I don't care about freeing in case of exception, but this habit helps me avoid leaking
Use RegisterExpectedMemoryLeak for the intentional memory leaks. The routine has a few overloaded versions of which one can be fead with an object class:
begin
RegisterExpectedMemoryLeak(TStringList);
FStringList := TStringList.Create;
...
or better, register the pointer itself:
begin
FStringList := TStringList.Create;
RegisterExpectedMemoryLeak(FStringList);
...
In this case the unexpected memory leaks will show up normally and can not be confused with this particular string list.
Let me answer by asking you a question.
Can you say for certain that the life cycle of the data module will always be tied to the lifetime of the application or that you will never need to create additional instances of it?
If you answer yes then feel free to ignore standard memory management practices.
If you answer no then you should make sure object's clean up after themselves.
Stuff gets done when you free an object, possibly more then only deallocating the memory.
Comes to mind a database object that does transactions and ends all started transactions in the ondestroy.
If you don't call free, ondestroy will not get fired and you may end up with locked tables.
I am looking for hints on how to debugging a crash in an application that uses the MS XML wrappers in the Delphi VCL. I suspect memory corruption, or some kind of obscure evil thing happening between objects and interfaces, such as reference counting bugs, or heap corruption. The question is, in effect: how do I debug such a crash?
This particular code makes heavy internal use of and extends on the base XmlIntf Interfaces (IXMLNode). ISomethingCustom is an interface that extends IXMLNode. THe problem happens where we crash somewhere in a recursive function that is passed an ISomethingCustom which is also (or supports also, in interface terms) IXMLNode.
boolean UtilityFunction( aNode: ISomethingCustom ):Boolean;
begin
if not Assigned(aNode) then exit; // this works. great.
if not Assigned(aNode.ParentNode) then exit; // this DOES NOT WORK.
// code that blows up if aNode.ParentNode is not assigned.
end;
The situation is that the aNode is also IXMLNode, and IXMLNode.ParentNode value is assigned (not nil), and yet it points to a COM object that may have been freed, destroyed, or corrupted somehow. I am trying to figure out WHAT is going on when an interface pointer can appear to be valid, but the object behind it has been nuked somehow.
Checking Assigned(aNode.ParentNode) returns TRUE, even when, if you were to attempt a cast in the debugger (at runtime only, not in the code), like this:
inspect/evaluate aNode
inspect/evaluate TInterfacedObject(aNode).ClassName
(works in Delphi 2010, at least!)
now cast TWhateverClassNameYouGotBefore(aNode).
In the debugger I now see that this is NIL. WHich may mean that
the magic "casting interface back to
the object" feature that is new in
delphi 2010, is failing.
I believe I am trying to debug a problem where heaps are corrupted, or COM objects are corrupt on the heap, because of a reference counting problem.
I really think that nobody should ever have the situation arise where an interface appears valid, but the object underneath has been deleted. I really would like to know what to do, and what is going on.
Although you haven't shown it in your code, your comments seem to indicate that you're type-casting the interface variable to a class type. That's not allowed. I've described why:
Why can’t I cast an interface reference to an object reference?
Interface references and object references don't point to the same things. Therefore, calling a method on one when the compiler thinks you have the other will yield unexpected results. You were unlucky because the code continued to run instead of crashing with an access violation, which would have been a bigger indication that you were doing something wrong.
My article above concludes by suggesting you use the JclSysUtils.GetImplementorOfInterface function from the JCL if you have a Delphi-implemented interface and the interface offers no function of its own for revealling the underlying object.
Wild guess: Have you tried to put aNode.ParentNode in a local variable and use it in the rest of the Utilityfunction:
function UtilityFunction(aNode: ISomethingCustom): Boolean;
var
lParentNode: INode;
begin
if not Assigned(aNode) then exit; // this works. great.
lParentNode := aNode.ParentNode;
if not Assigned(lParentNode) then exit;
// code that uses lParentNode.
end;
My suggestion is to make sure that the ParentNode function is actually called in Assigned(aNode.ParentNode). There are some nasty corner-cases in Delphi where a procedure/function without arguments doesn't get called, but rather it's reference is taken when you omit the parenthesis's.
Try to change it to Assigned(Anode.ParentNode()) (which should have the same effect as François suggestion).
I have read A case against FreeAndNil but still don't understand why I cannot use this method in a class destructor ? Can anyone explain.
Update: I think the comment from Eric Grange was most useful for me. The link show that this is not obvious how to deal with it and it is mainly a matter of taste. Also the method FreeAndInvalidate was useful.
The problem with that is that many
seem to use FreeAndNil as some magic
bullet that will slay that mysterious
crash dragon. If using FreeAndNil() in
the destructor seems to solve a crash
or other memory corruption problems,
then you should be digging deeper into
the real cause. When I see this, the
first question I ask is, why is the
instance field being accessed after
that instance was destroyed? That
typically points to a design problem.
It argues that it hides the real problem you have. It must mean your code is accessing properties/fields/methods of an object that is already destroyed (the destructor is called). So instead of hiding the real problem with FreeAndNil you should really be solving the underlying problem.
This code below would not crash if you would use FreeAndNil PropertyA in the destructor of SomeObject. But it hides the real problem that SomeObject is used after it is destroyed. It is better to solve this design problem (accessing destroyed objects) instead of hiding it.
SomeObject.Free; // Destructor called
if Assigned(SomeObject.PropertyA) then // SomeObject is destroyed, but still used
SomeObject.PropertyA.Method1;
EDIT
On the other case, one could argue that if FreeAndNil is not used, the code would not crash either. Since even though the object is destroyed, the memory might not be reused and all structures might be in tact. The code above might even run without problems if Free is used to destroy PropertyA instead of FreeAndNil.
And if FreeAndNil was used to destroy SomeObject, you would also see the real problem no matter what the code in the destructor is.
So although I agree with the argument that it could hide the real design flaw and personally do not use FreeAndNil in destructors, it is not some magic bullet to discover such design flaws.
The issue is fairly easy to explain, and the contention around this issue is more subjective than objective. The use of FreeAndNil is simply unnecessary if the variable reference to the object being freed will go out of scope:
procedure Test;
var
LObj: TObject;
begin
LObj := TObject.Create;
try
{...Do work...}
finally
//The LObj variable is going out of scope here,
// so don't bother nilling it. No other code can access LObj.
//FreeAndNil(LObj);
LObj.Free;
end;
end;
In the above code snippet, nilling the LObj variable would be pointless, for the reason given. However, if an object variable can be instantiated and freed several times during the lifetime of an app, then it becomes necessary to check whether the object is indeed instantiated or not. The easy way to check this is whether the object reference has been set to nil. In order to facilitate that setting to nil, the FreeAndNil() method will both free the resources, and set nil for you. Then, in code you can check to see whether the object is instantiated with either LObj = nil or Assigned(LObj).
The case of whether to use .Free or FreeAndNil() in object destructors is a grey area, but for the most part, .Free should be safe, and nilling the references to sub-objects in the destructor should be unnecessary. There are various arguments around how to deal with exceptions in constructors and destructors.
Now pay attention: if you prefer to pick and choose whether to use .Free or FreeAndNil() depending on the specific circumstances outlined above, that's fine, but note that the cost of a bug due to not nilling a freed object reference that is subsequently accessed can be very high. If the pointer is subsequently accessed (object freed but reference not set to nil), it can happen that you are unlucky and the detection of memory corruption occurs many lines of code away from the access to the freed-but-unnilled object reference. This kind of bug can take a very long time to fix, and yes, I know how to use FastMM.
Therefore for some people, including me, it has become habit (a lazy one, perhaps) to simply nil all object pointers when they're freed, even when the nilling is not strictly necessary.
I tended to use FreeAndNil fairly often (for whatever reason) but not anymore. What made me stop doing this is not related to whether the variable needs to be nil afterwards or not. It is related to code changes, especially type changes of variables.
I got bitten several times after changing the type of a variable from TSomething to an interface type ISomething. FreeAndNil doesn't complain and happily continues doing its job on the interface variable. This sometimes lead to mysterious crashes which could not be immediately followed back to the place where it happened and took some time to find.
So I switched back to calling Free. And when I deem it necessary I set the variable to nil afterwards explicitly.
i hunted down a stackoverflow question talking about FreeAndNil and FreeAndInvalidate to mention that the Microsoft Security Development Lifecycle now recommends something similar to FreeAndInvalidate:
In light of the SDL recommendation above – and a number of real bugs related to reuse of stale references to deleted C++ objects...
The obvious choice of sanitization value is NULL. However there are downsides to that: we know that a large number of application crashes are due to NULL pointer dereferences. Choosing NULL as a sanitization value would mean that new crashes introduced by this feature may be less likely to stand out to a developer as needing a proper solution – i.e. proper management of C++ object lifetimes – rather than just a NULL check that suppresses the immediate symptom.
Also checks for NULL are a common code construct meaning that an existing check for NULL combined with using NULL as a sanitization value could fortuitously hide a genuine memory safety issue whose root cause really does needs addressing.
For this reason we have chosen 0x8123 as a sanitization value – from an operating system perspective this is in the same memory page as the zero address (NULL), but an access violation at 0x8123 will better stand out to the developer as needing more detailed attention.
So basically:
procedure FreeAndInvalidate(var obj);
var
temp : TObject;
const
INVALID_ADDRESS = $8123; //address on same page as zero address (nil)
begin
//Note: Code is public domain. No attribution required.
temp := TObject(obj);
Pointer(obj) := Pointer(INVALID_ADDRESS);
temp.Free;
end;
I haven't been able to find the answers to a couple of my Delphi memory management questions. I could test different scenarios (which I did to find out what breaks the FreeAndNil method), but its takes too long and its hard! But seriously, I would also like to know how you all (Delphi developers) handle these memory management issues.
My Questions (Feel free to pose your own I'm sure the answers to them will help me too):
Does FreeAndNil work for COM objects? My thoughts are I don't need it, but if all I need to do is set it to nil than why not stay consistent in my finally block and use FreeAndNil for everything?
Whats the proper way to clean up static arrays (myArr : Array[0..5] of TObject). I can't FreeAndNil it, so is it good enough to just set it to nil (do I need to do that after I've FreeAnNil'd each object?)?
Thanks Guys!
COM objects are referenced via Interfaces, which you don't need to do anything to free. The compiler takes care of the necessary reference-counting logic to make sure the COM object will be disposed of at the right time.
As for static arrays, (or dynamic arrays, for that matter,) they don't need to be freed by you either. If they contain objects then the objects have to be freed at the appropriate time, but the arrays don't.
Also, never use FreeAndNil on anything that's not an object reference. Using it with interfaces or other variables can corrupt memory. It's best to never use it (use Free instead) unless you're dealing with an object that you need to free and then reuse later.
First, in most situation, FreeAndNil is a bit of overkill. It's handy when you free and object's field outside it's destructor, or on a global(ugly) variable. But most of the time, just calling free is enough.
As you should know, an object variable is actually a pointer to the object's data. When you call Free, that buffer is freed (after the destructor is ran, of course), but the Object variable still points to the memory position that was just freed. It's called a "Dangling pointer". Having a dangling pointer is not a problem as long as you KNOW it's dangling in that context. For exemple:
Procedure Myproc;
var vString : TStringList;
begin
//Here, vString is "dangling"
vString := TStringList.Create;
//Here, vString is valid
try
//Do some stuff
finally
vString.Free;
end;
//Here, vString is "dangling"... But who care, it's about to go out of scope and we won't use it again.
end;
Calling FreeAndNil makes more sense on global variable where you don't know exactly when or how the variable can be freed. With that being said, there is nothing wrong in calling FreeAndNil all the time (except in very tight loops where you try to get every oz of performance).
Now, for the COM objects... Like Mason stated, they are reference counted. So if you hold the only reference to that interface, calling MyInterface := nil; will free it. But when/if the variable goes out of scope, the compiler take care of adding cleanup code to make sure the interface reference is decremented. So if you are trying to keep the memory requirement to a minimum, set the interface to nil. Otherwise, it doesn't matter that much.
As for your array... You can just call Free on every items in the list... Optionnaly set them to nil after.
Regarding static arrays, if you created the contents of the array, just free those objects you created. You don't need to do anything special to clean up the space used by myArr itself.
COM objects are automatically reference counted; as soon as variable goes out of scope or the object that has the interface pointer as a field is deleted Delphi will call _Release and the object will delete itself. You don't need to set anything to nil explicitly.
For static arrays you need to loop over them and free each object explicitly.