Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why are Delphi objects assigned even after calling .Free?

Tags:

In Delphi, why does the Assigned() function still return True after I call the destructor?

The below example code will write "sl is still assigned" to the console.

However, I can call FreeAndNil(sl); and it won't be assigned.

I've been programming in Delphi for a while, but this never made sense to me.

Can someone explain?

program Project1; {$APPTYPE CONSOLE} uses SysUtils, Classes;  var   sl : TStringList;  begin   sl := TStringList.Create;   sl.Free;   if Assigned(sl) then     WriteLn('sl is still assigned')   else     WriteLn('sl is not assigned'); end. 

I tried comparing the VCL operations... FreeAndNil is short and sweet and makes sense:

procedure FreeAndNil(var Obj); var   P: TObject; begin   P := TObject(Obj);   TObject(Obj) := nil;  // clear the reference before destroying the object   P.Free; end; 

But TObject.Free is in mysterious assembler, which I don't understand:

procedure TObject.Free; asm         TEST    EAX,EAX         JE      @@exit         MOV     ECX,[EAX]         MOV     DL,1         CALL    dword ptr [ECX].vmtDestroy @@exit: end; 
like image 433
JosephStyons Avatar asked Oct 24 '08 19:10

JosephStyons


1 Answers

If you use sl.Free, the object is freed but the variable sl still points to the now invalid memory.

Use FreeAndNil(sl) to both free the object and clear the pointer.

By the way, if you do:

var   sl1, sl2: TStringList; begin   sl1 := TStringList.Create;   sl2 := sl1;   FreeAndNil(sl1);   // sl2 is still assigned and must be cleared separately (not with FreeAndNil because it points to the already freed object.) end;     procedure TObject.Free; asm     TEST    EAX,EAX     JE      @@exit              // Jump to exit if pointer is nil.     MOV     ECX,[EAX]                MOV     DL,1     CALL    dword ptr [ECX].vmtDestroy  // Call cleanup code (and destructor). @@exit: end; 
like image 77
Toon Krijthe Avatar answered Sep 19 '22 13:09

Toon Krijthe