Why should you always use FreeAndNil instead of Free.

This post was written by Alexander on April 28, 2009

Well, when someone talks about object creation and destruction, he usually imagine something like this:

...
var
  SomeObj: TSomeClass;
...
  SomeObj := TSomeClass.Create;
  try
    ...
  finally
    SomeObj.Free;
  end;
...

However, I want to show that you should avoid “Free” call, whenever possible – by replacing it with call to FreeAndNil, for example:

...
var
  SomeObj: TSomeClass;
...
  SomeObj := TSomeClass.Create;
  try
    ...
  finally
    FreeAndNil(SomeObj);
  end;
...

Please, note, that I mean replacing Free -> FreeAndNil everywhere. I talk not about just using FreeAndNil, when you want to use “Assigned(SomeObj)”, but I really mean everywhere – by do not using Free at all. Yes, including cases with local variables.

Why? The reason is simple: there is no reason for not-doing it. And this post explains why it is so.

When you tell this to common Delphi developer, there are high chances that he’ll vote against it, saying:

1. Free + nil is not full equivalent of FreeAndNil. FreeAndNil clear pointer first and calls destructor second. If your code uses this reference – it will no longer work. For example, if we clear class field, but some internal class uses it during destruction process.

Well, I count it as advantage. It helps to catch bad-design. Because you just described a case, when your code either uses variable instead of Self (i.e. Form1.SomeObj instead of SomeObj) or accesses a partial-constructed object (actually, it is more like partially deleted object now). And by using FreeAndNil you can catch these cases.
Yes, such situations can be made “by-design”, but even so – you will detect an error immediately (obviosly, there will be Access Violation), so you can revert changes back, if you don’t want to redesign your code.

2. So what are examples of righteous/warrantable usage of FreeAndNil?

Hmm, it is not very clear, what example can be provided here. Excluding complicated examples (like in previous block), your code will work the very same way – with or without FreeAndNil. Replacing Free -> FreeAndNil – it is a pure optional action.
You can compare FreeAndNil with seat (safety) belts in cars: if you application runs normally – then FreeAndNil won’t be useful. But if your code mess up with something – then FreeAndNil (as seat belts too) will protect you from consequences. By clearing the reference, FreeAndNil will help you to catch your wrong access immediately. Without it (i.e. by using Free only), your code may continue to run (even without raising an exception) and gave the wrong results or damage global state. It is quite dangerous.
Note, that FreeAndNil is still not enough to fully cover those bad cases – because you can access one object through multiply variables. FreeAndNil will clear one reference, but it won’t touch others. A good example here is all kinds of lists of objects.

3. There is no need for FreeAndNil here! (i.e.: local variables)

Well, local variable can be refactored into global later. FreeAndNil will protect you from misuses (just Free is not). Large amount of code is done by using copy-paste. That is why someone can pick your code, copy it into another place (where variable has different scope or is used multiply times), then he’ll be in trouble – if you didn’t use FreeAndNil (and this “he” may be even you, but few months later). Besides, if you have large routine then you may just not notice, that you have used variable few times (for example – in cycle). By always using FreeAndNil you’ll make your code bullet-proof for modifications.
Moreover, it is just convient, when you have FreeAndNil everywhere, instead of mix of Free/FreeAndNil. And you don’t even need to think about it: “gosh, should I put FreeAndNil here or just Free is enough?!!”.

If you think that FreeAndNil is still overkill in certain case – then why don’t you use Destroy call? Indeed, the Free is overkill in many situations too!
Note, that object’s destructor is not called in 99% of Delphi’s code (a call to procedure is used instead). Then why don’t we take a step further and don’t use FreeAndNil instead? The benefit of using FreeAndNil is far greater then benefit from using Free instead of Destroy. Why? Well, if the first case we got the protection from very tricky mistakes (like I said – it is not panacea, but still a good bonus). And in the second case you got only ability to skip writing additional “if”. Why? Because if you call Destroy for nil-variable, you’ll get an AV immediately (because Self = nil, so any access to object’s field will trigger an undoubted AV). So, there is no problem at all – you will fix the code instantly. Compare this with case, when your code silently produce wrong results!
Furthermore, you can not giveup for a bonus “less writing” by implementing a routine “F”, which simply calls FreeAndNil.

4. Using Free instead of Destroy is recommended by CodeGear! And I never heard of such recommendation for FreeAndNil.

Well, we already examined arguments that Free -> FreeAndNil transition will have more benefits than (already happened) transition Destroy -> Free. Now, don’t you think that argument of not having official approval from CG does look quite dull?

5. Nevertheless, majority of people (who heard about this idea) will continue to claim that this is still overkill.

Why?

The most called reason is the force of the habit: “I write Free automatically, even without thinking”.
Well, actually, this argument is quite serious.

By in this post, I want to show you that there are good reasons to reconsider/change this habbit. Of course, there should be a really good reson for broking your habbits. And here it comes…

6. Safety of your code.

Many people says (and they, indeed, believe so) that experienced programmer can use FreeAndNil only in nessesary places. In all other cases there is no need to clear the object’s reference – so you can use Free.

But that is so wrong: you can not know that.

Imagine, that destructor of your object deletes its object-field by using Free (such common action, right?). The destructor for this sub-object calls a virtual method as part of its destruction process. This method can be empty in base class. Well, so far so good.
Now, someone (or may be you, few months later) will take these classes and override this virtual method. Now he will call another (virtual) method, which belongs to your first mentioned object. And this method (may be also in yet another child class) will try to use already deleted field in your first object. Suppose that this access will run ok (i.e. memory manager do not release this memory yet), but the global state of the application will be damaged forever. Ooops.
FreeAndNil will guard you from this situation (by raising 100% AV), and Free is not.

Why did I mention virtual methods here? That is why you cann’t say: “I know what I am doing – there is no need for FreeAndNil here”. As you can see – you can not know that! Yes, two of your base classes is all good with it, but the very usual code in child classes can lead to the darkest error in the entire class hierarchy. Yes, it is not actually your fault (unless you are also responsible for child classes too), but shouldn’t your code be ideal? And, yes, there is a bug in child class (by calling inadmissible method), but how will you catch it? Without FreeAndNil it is very hard to do.

Okay, even if you still insist on putting FreeAndNil only, when it is nessesary – then we just gave an example, when it is simply not obvious. If you have a habbit of using Free, then you can not even think about considering this case as worth adding FreeAndNil! That is where all problems come. You’ll just put Free call here (as usual) and go somewhere else. And then spend a few days for debugging this tiny, nasty problem later.
By using FreeAndNil everywhere you’ll dispose those problems (should I put it there or not?) – just put it everywhere! Like I said: FreeAndNil – is a safety belts. And realizing it is the only thing left.

Summary: from my point of view – the bonus of protection against fickle/implicit errors outweigh the need to change the habbit.

_________________________________________________________

So.

Why wait? Why don’t use FreeAndNil everywhere, starting today? If you’ll make this your habbit – then you lose nothing, but gain very powerful bonus.

Nevertheless, I suspect that many Delphi programmers, even if they admit this idea, won’t change their practice – just because “someone has said something”. They do not meet with this situation – then it do not exists. So they’ll wait until the bug strike them hard. I’ll repeat it again: FreeAndNil is a safety belt. It protect you from bugs, that not happens yet.

Remark: this long post is just my opinion – feel free to reject it, if you (still) don’t like it.

_________________________________________________________

When you reference an object via more than one reference, you can mistakenly use already disposed object or free the very same object twice. The FreeAndNil gives you protection only if you mistakenly use the object after its dispose, when you have only one reference.

So, even if you use FreeAndNil, you still need an additional checks. And if you have large project and suddenly changes all Free calls to FreeAndNil – then there are good chances then you’ll run into problems. You’ll probably detect many kind of misuses. To track down these problems you’ll need a tool.

Such checks can be found in EurekaLog. We will talk about its memory-related features in more details later (yes, about FastMM too), and now I want to give only brief overview.

EurekaLog's memory-leaks properties

EurekaLog’s memory-leak feature settings

Once enabled, this feature can detect a various memory misuse cases and report them through usual exception notification process in EL. Those cases includes double-free and writes to already freed memory. Similar features are very common in advanced memory managers (like FastMM, for example).

It is quite powerful feature, but just don’t forget that EurekaLog is a debugging tool. It is not essential part of Delphi language. You should not write code, which relies on its presence. I.e. you should not forget about FreeAndNil, hoping that EurekaLog will handle all bad cases for you. Besides, there still can be complex (and, actually, rare) situations, when EurekaLog’s features can not catch attempt of invalid memory access (it is not limitation of EL, the same is correct for other tools too). More on this topic later.

Apart from using FreeAndNil and diagnostic features in EurekaLog or MM, you should try to minimize references to each objects and try to use some sort of automatic management. For example, if your object can be included in the list, then it is good to add code, which removes object from any list it belongs to on deletion (there is an example in VCL – it is Components list-property).

Another approach is using interfaces with reference counting. Well, actually, you should be careful there: if you mix manual control of life-time (manual call to destructor) and automatic control (using reference counting in interfaces) – then things will go from bad to worse. But if you use only pure interfaces, then you’ll automatically get rid of such errors: compiler (well, your application at runtime) will look after your objects, not allowing their misuses.

This post was written by Alexander on April 28, 2009
Posted Under: Delphi Tags: ,

Reader Comments

Olaf Monien:

Count me in. I’m preaching FreeAndNil since quite a while ealready ;-)


#1 
Written by Olaf Monien on April 28th, 2009 @ 10:24
Xepol:

It also leaves a lot less loose(invalid) pointers floating on the stack if you do any lower level debugging.

Yes, I was indeed able to find a number of reference after the object was free usages this way. These were, of course, in very unusual and seldom used code paths. However, because the memory manager does not zero memory when you free it, often these calls either succeeded or randomly did very, very strange things. Once FreeAndNil replaces .Free, most of these mistakes crash in the same way (copies of pointers are obviously the exception here – I avoid making copies of pointers whereever possible because of that)

It definitely improved my code.

Oh, and for those cases where exceptions are not an option, I also have a SafeFreeAndNil with supresses any exceptions with a try FreeAndNil Except End; – Ever have a form that shows and error dialog and then refuses to close when you close it? Exceptions in OnClose can be evil.


#2 
Written by Xepol on April 28th, 2009 @ 11:04
Alexander:

>>> try FreeAndNil Except End
Personally, I vote against such practice (silently exception hiding). You are correct about evil exceptions in Close and destructors, but I prefer another approach (for example – global try/except in on close + terminate application on exception).
May be I’ll make a post on this theme too.


#3 
Written by Alexander on April 28th, 2009 @ 11:35
Eric:

Xepol, your SafeFreeAndNil is anything but safe, before a full blown exception gets triggered, your code could have done any amount of damage other live or stored data.
An exception, unless it’s a very specific one that was emitted in very specific controlled conditions should lead to an immediate termination of the application (only thing you’re allowed to is log the context, stack, etc.).
If an unexpected exception happens, it means that your code has been doing unexpected things, and thus should be terminated ASAP before it has a chance of doing permanent damage (such as corrupting data, performing illegal actions, allowing a hacker into the system, etc.)


#4 
Written by Eric on April 28th, 2009 @ 14:15
Jolyon Smith:

Whilst I agree to a certain extent, I disagree with some of your arguments.

Specifically in the case of a local variable that has a single use confined to a try..finally.

You suggest that FreeAndNIL() offers protection against refactoring. I suggest it offers protection only against LAZY refactoring.

If as much care is put into refactoring as is put into creating that procedure then no protection is needed (the refactored code will be properly adjusted).

Offering that protection *invites* lazy refactoring which in turn is likely to lead to *other* mistakes.

The use of a seat belt metaphor was an interesting choice as the history of compulsory seat belts makes this point very well.

http://www.geocities.com/galwaycyclist/info/seatbelts.html

Of course the statistics all say that seat belts save lives. But they also say that they cause accidents and in some cases cause deaths.

The lives saved are those of car users, but pedestrians and other road users pay the price of riskier and less safe driving of those “protected” by seat belts.

Lower “car user fatality” rates come at the expense of higher overall accident rates.

In this case, protecting refactorers against mistakes with Free could encourage them to be lazy about other aspects of their refactoring and therefore likely to make other mistakes.

That’s just another way of thinking about it.

:)

But overall I agree that FreeAndNIL() should be used in most places, but I disagree that it should be used in all *if* the rationale for that is that it’s some sort of guarantee against memory management errors.

In my experience people make most mistakes when they become complacent and believe that they *can’t* make mistakes.


#5 
Written by Jolyon Smith on April 28th, 2009 @ 14:59
John E:

Excellent points. One argument that I use with my peers is that code is to be self documenting and states truth. If your pointer references an object that does not exist… that is a lie. Lies in code is the number one cause for bugs. Think about it. That is why we have to step through the code… to find out the truth.


#6 
Written by John E on April 28th, 2009 @ 16:46
Thomas Mueller:

You are so right! I never actually thought about the uninitialized field issue in a destructor calling a virtual method.


#7 
Written by Thomas Mueller on April 28th, 2009 @ 16:57
Gerry Coll:

But: FreeAndNil can stop the compiler from helping you:

I just had to fix a method (written by someone else) where using FreeAndNil(Obj) on an OPTIONALLY created object stopped the compiler from issuing a

“[Pascal Warning] Test.pas(177): W1036 Variable ‘Obj’ might not have been initialized” message, as passing an uninitialised var as an untyped var parameter is OK.

So the “finally FreeAndNil(Obj) end;” threw an access violation

If the other developer had used Free, they would have seen the warning, and corrected their mistake.


#8 
Written by Gerry Coll on April 29th, 2009 @ 00:49
Steve Woods:

Also, as a word of caution, I recently came across a case in code where when .free was replaced with FreeAndNil it crashed. This was due to the fact that in FreeAndNil, the original reference is set to Nil BEFORE the object had been destroyed, and code executed during this destructor (off an event) needed this reference (which was still valid).


#9 
Written by Steve Woods on April 29th, 2009 @ 08:09
Alexander:

Thanks to all for the replies :)

2 Steve Woods: actually, I’ve considered this issue – see item #1.


#10 
Written by Alexander on April 29th, 2009 @ 09:03
Smasher:

What about something like

for I := 0 to DatabaseList.Count – 1 do
DatabaseList [I].Free;

Can’t use FreeAndNil here or is there a possibility?


#11 
Written by Smasher on April 29th, 2009 @ 14:29
Alexander:

2Smasher:

You can use something like:

for I := 0 to DatabaseList.Count – 1 do
begin
DatabaseList[I].Free;
DatabaseList[I] := nil;
end;

But this depends on what kind of list class do you use.
There definitely can be situations, where using of FreeAndNil (or its analog) is impossible.


#12 
Written by Alexander on April 29th, 2009 @ 15:09
Rudy Velthuis:

I thoroughly DISagree. When software is written well, there is hardly ever a need to use FreeAndNil. If the object you freed is still accessible, it should probably not be freed yet. If it is not accessible anymore (e.g. in the destructor of another object), setting it to nil serves no purpose.

IME, a design that needs the use of FreeAndNil should be revisited.

IOW, there is hardly ever a need to use FreeAndNil. A frequent need for FreeAndNil is IMO often a symptom of bad design.


#13 
Written by Rudy Velthuis on May 2nd, 2009 @ 00:30
Alexander:

2Rudy Velthuis:

>>> When software is written well, there is hardly ever a need to use FreeAndNil
How do you know that your software is “written well”? How do you know that your code has no mistake of accessing already freed object? By assigning nil to object reference you’ll catch those errors instantly.

>>> If the object you freed is still accessible, it should probably not be freed yet
Consider this example:

var S: TStringList;

S := TStringList.Create;
try
S.Add(’gg’);
finally
S.Free;
end;

Caption := IntToStr(S.Count);

There are very high changes that this buggy code will run without single glitch. Even more: it will give the proper results!
The object in the last line WAS freed AND it IS still accessible.

>>> IME, a design that needs the use of FreeAndNil should be revisited
You probably missed my point here. I’m not talking about such design here. I’m talking about using nil to catch errors like accessing already freed object. The code itself does not need these FreeAndNil calls to function. It’s just a safety belts.


#14 
Written by Alexander on May 3rd, 2009 @ 08:53
Xepol:

Alexander -> Sometimes a memory leak or a resource leak is more acceptable than total application failure.

Sure, you want to absolutely want to catch as many errors as possible in development and testing, but your deployed app should be more robust. A minor glitch or failure should not keep unrelated parts of the application from functioning.

In fact, a custom FreeAndNil routine can be tailored to your needs in that situation AND allow your deployed application to not simply vanish off screen simply because you had an unexpected edge condition.


#15 
Written by Xepol on May 3rd, 2009 @ 22:26
Alexander:

Surely I can’t dictate your strategy :D I just share some of my thoughts – that is all. Feel free to decline them ;)

I just want to note that the question here is not about just simple memory leak, but rather subtle bugs, that can appears from accessing a deleted objects.

Consider my last example with TStringList. What if you will make some kind of desicion, based on the data from already freed object? I.e.:

if S.Count = 0 then
// user profile is empty – so we can safely delete it.
DeleteUserProfile(CurrentProfile);

In this example the bug of accessing already deleted object can lead to deletion of valid user profile. Surely, that is far more severe than simple memory leak, isn’t it?

BTW, the Access Violation from FreeAndNil won’t lead to closing your application (I mean the usual VCL Delphi application). There would be an error dialog and you still could continue working. There is nothing like “vanish off screen” here.


#16 
Written by Alexander on May 4th, 2009 @ 09:17
Alexander:

2 Gerry Coll:
Good point, but this is not very scary, as there is a simple rule to find those mistakes.
How should one should implement a situation, where he need optionally create an object?

[CODE]Obj := nil; // or Obj := TObj.Create for always creating
try

Obj := TObj.Create; // only for optional creating

finally
FreeAndNil(Obj); // or Obj.Free;
end;[/CODE]

So, this mistake can be easily spotted: if you see Free/FreeAndNil outside of try/finally for local object – this is mistake. If you see that there is no assignment right before try (when there is Free/FreeAndNil in its finally) – this is a mistake.

So, the rules are simple:
1). Every allocation for local object must use try/finally.
2). There must be an assigment right before try for finally with deleting some local object.

Just browse through your code and you’ll catch those errors.


#17 
Written by Alexander on May 4th, 2009 @ 14:59
Gerry Coll:

My point here is that is wasn’t my code, and it was buried in a fairly complex method, with two try..finally blocks (NOT MY DESIGN).
If the developer had used .Free, the mistake would have been obvious. I found it when doing a quick integration test of the code.


#18 
Written by Gerry Coll on May 5th, 2009 @ 02:39
Thomas Mueller:

I agree, mostly, but there is one major problem with always using FreeAndNil:
If at some later time you decide that you want to replace a class instance by an interface, the compiler will happily call FreeAndNil on that interface variable and this will crash your program. If instead you had called Free, the compiler would have found that error for you.


#19 
Written by Thomas Mueller on July 22nd, 2009 @ 07:17
Ludek:

#19: you are absolutely right, i also missed this big contra in the text. Next problem is refactoring to a record – the same issue. Code perfectly compiles, but does not run.
It can be avoided on d2009 using some generic code – but the appropriate call is then a “bit” long (because of poorly implemented type inferring on procedures with “var” and of nonexistence of generic global procedures :/)

next thing a have to write – refactoring to a global variable is no argument, as it is silly. there is no need for global variables at all in most application. perhaps for some private ones in unit’s implementation section… or some really-crazy-nearly-to-death-optimized-code. our some MLines long project does not contains any public global variable.

last thing – the overusage of freeandnil makes the code hard to read.
The usage of freeandnil tells me – watch out! There is something weird with that variable! code full of “freeandnil” tells me – go away, don’t start making anything with that, you won’t ever understand it, it has been programmed by a fool…

i even hate using .free at places, where is it not necessary. but I learnt it many years ago – and i’m unable to get rid of it :(


#20 
Written by Ludek on August 24th, 2009 @ 18:01
Alexander:

I’ve added a suggestion about FreeAndNil to Quality Central: it is report #76967.


#21 
Written by Alexander on August 25th, 2009 @ 07:05

Add a Comment

required, use real name
required, will not be published
optional, your blog address