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;
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;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With