【发布时间】:2010-09-19 02:24:36
【问题描述】:
在Delphi中,为什么调用析构函数后Assigned()函数还是返回True?
下面的示例代码会将“sl is still assigned”写入控制台。
但是,我可以调用 FreeAndNil(sl);并且不会被分配。
我在 Delphi 中编程已经有一段时间了,但这对我来说毫无意义。
谁能解释一下?
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.
我尝试比较 VCL 操作... FreeAndNil 短小精悍且有意义:
procedure FreeAndNil(var Obj);
var
P: TObject;
begin
P := TObject(Obj);
TObject(Obj) := nil; // clear the reference before destroying the object
P.Free;
end;
但是 TObject.Free 在神秘的汇编器中,我不明白:
procedure TObject.Free;
asm
TEST EAX,EAX
JE @@exit
MOV ECX,[EAX]
MOV DL,1
CALL dword ptr [ECX].vmtDestroy
@@exit:
end;
【问题讨论】:
-
这个问题展示了程序员如何将一个范围内的变量名与堆上存在的对象混为一谈。该对象实际上是堆上的内存,并且 Free 释放堆上的内存,但是该方法不可能擦除包含对对象的引用的局部变量,但它不是对象本身。尽管作为对象指针的 delphi 对象引用中的指针语义大部分是隐藏的,但这是底层指针实现泄漏的一种情况。
标签: delphi