Friday, 5 September 2014

Difference between Free and FreeAndNil in Delphi: What to use when?

Difference between Free and FreeAndNil in Delphi: What to use when?

Free and FreeAndNil are the main concepts of memory management in Delphi. FreeAndNil is a function declared in the SysUtils unit and was introduced in Delphi 5. Below is the implementation of FreeAndNil:

procedure FreeAndNil(var Obj);
var
  Temp: TObject;
begin
  Temp := TObject(Obj);
  Pointer(Obj) := nil;
  Temp.Free;
end;

Difference between Free and FreeAndNil: 

FreeAndNil first sets the object reference to nil and then frees the object. 

When to use FreeAndNil instead of Free?

If you want a rational answer, the question to ask is, why would you want to set an object reference to nil once you’re done with it?  And there’s only one good reason to ever do that: If you want to reuse the variable later.  There are some times when you’ll have an object that may or may not be initialized. If it’s not, then the variable will be nil, and if you find it’s nil, then you create it before using it.  This is a pretty common pattern.  It’s called “lazy creation”.  But every once in a while, you want to use lazy creation on an object, then destroy it and create it again. This is when FreeAndNil comes in handy.

Use FreeAndNil for Defensive Programming

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 will give the wrong results or damage global state. It is quite dangerous situation and may lead to corrupt your data too. By not setting it to nil (in case of Free)- you're lying to the compiler. You're telling that there is allocated memory at this location, and the truth is that it isn't. And lying to machine just isn't good. FreeAndNil is very strict in these situation will immediately give you Access Violation error which I think is good thing and you can fix the problem on the spot because you know the problem!! Compare this with case, when your code silently produce wrong results! By always using FreeAndNil you’ll make your code bullet-proof for modifications.

Example of FreeAndNil

var
  myList : TList;
begin
  try
    myList := TList.Create;
    ....
    ....
  finally
    FreeAndNil(myList);
  end;
end;