FreeAndNil为什么Free以后还要Nil?什么情况下用FreeAndNil? ( 积分: 20 )

  • 主题发起人 主题发起人 ynduanlian
  • 开始时间 开始时间
Y

ynduanlian

Unregistered / Unconfirmed
GUEST, unregistred user!
在SysUtils中FreeAndNil是这样实现的:
procedure FreeAndNil(var Obj);
var
Temp: TObject;
begin
Temp := TObject(Obj);
Pointer(Obj) := nil;
Temp.Free;
end;
我觉得很困惑,为什么通常看到的例程,通程都只用TXXX.Free这样就可以了,哪种情况下需要用这个FreeAndNil函数?
 
在SysUtils中FreeAndNil是这样实现的:
procedure FreeAndNil(var Obj);
var
Temp: TObject;
begin
Temp := TObject(Obj);
Pointer(Obj) := nil;
Temp.Free;
end;
我觉得很困惑,为什么通常看到的例程,通程都只用TXXX.Free这样就可以了,哪种情况下需要用这个FreeAndNil函数?
 
指针--->一块内存
一般地都需要free,nil
var
btn :Tbutton;
begin
btn :=Tbutton.create(self);
btn.free;
btn :=nil;
end;
如果
with Tbutton.create(self) do
begin
....
free.此时只要free即可,
end;
 
楼上的,请看Delphi中帮助文档自带的说明IniFile使用的例程,并没有用XXX=Nil吧?
而且上面的btn是TButton的一个对象,而不是对象的指针吧?

procedure TForm1.Button2Click(Sender: TObject);

var
MyIniFile: TIniFile;
begin

MyIniFile := TIniFile.Create('myapp.ini');

{ if the entry wasn抰 there before, delete it now }
if Memo1.Lines.Values['Title1'] = '' then
MyIniFile.DeleteKey('Transfer', 'Title1')
{ otherwise, restore the old value }
else
MyIniFile.WriteString('Transfer', 'Title1', Memo1.Lines.Values['Title1']);
MyIniFile.Free;
end;
 
var
obj: TObject
在这样的声明中,obj实际上是一个指指针。
Obj.Free 只是将Obj指向的内存释放了,但是Obj本身依然保存着这个刚刚释放的内存地址。
如果在你程序的一个地方只是简单地Obj.free
那么在程序的其它地方,就无法知道Obj指向的对象实例到底是释放了还是没有释放。
也就是说Obj成了C语言中总强调的“野”指针[:D](有内容,但是指向的内容却被释放了)
FreeAndNil的好处就是,在释放了Obj指向的内容后,顺手将obj本身也设置为nil
这样,在程序的其它地方,只需要判断Obj是否等于nil就知道对象是否存在
 
那么为什么Delphi自带的例程,几乎都只用Free而几乎很少见到有用FreeAndNil的例子呢,难道后者所做的工作不是更完全吗?
 
那是因为是局部变量,随着声明局部变量的过程或者函数的结束,局部变量本身就不存在了,你需要为一个即将消亡的指针置空吗?
不要因为Delphi自己带的代码怎样就觉得那肯定对,Delphi代码也是人作的,一样会有Bug
但是,就这个问题,他们这么处理(没有置空)没有毛病
 
多人接受答案了。
 
一般来说,你申请的内存,你用完后释放的时候,一般来说要设定为nil,因为很多判断都是根据指针是不是nil来进行下面的步骤的,其中Free方法也不例外,如果你虽然释放了一个指针但你没有初试化它为nil,则Free会引发异常的.也就是Free会检查是否nil,如果是nil它就会自动返回的.
 
后退
顶部