Monday, January 2, 2006

Why do I get AVs when freeing an object?

This is generally caused by trying to free an already freed object.

The Free method is written to not destroy a nil pointer. This leads programmers to believe that Free will set the pointer to nil when it is done, therefore making Free safe to call again. This is not true. Why you ask? Because there may be multiple pointers to the same object. Consider example one.

It is generally a good programming practice, particularly when the object's variable has a scope larger than a procedure, to set the variable to nil immediately following a Free. See example two. Alternatively, in later versions of Delphi, the FreeAndNil method from the SysUtils unit could be called as in example three.
procedure example1;
var
obj1, obj2: TObject;
begin
obj1 := TObject.Create; { This creates an object }
obj2 := obj1; { There is still only one object, just two things pointing to it }
obj1.Free; { If Free set obj1 to nil, how would it know about obj2? }
obj2.Free; { This will cause an AV }
end;

procedure example2;
var
obj1: TObject;
begin
obj1 := TObject.Create;
obj1.Free; obj1 := nil; { This makes obj1.Free safe to call again }
obj1.Free; { This will not cause an AV }
end;

procedure example3;
var
obj1: TObject;
begin
obj1 := TObject.Create;
FreeAndNil(obj1); { This makes obj1.Free safe to call again }
obj1.Free; { This will not cause an AV }
end;

No comments: