Delphi syntax:
function Assigned(const P): Boolean;
Description
Use Assigned to determine whether the pointer or procedure referenced by P is nil. P must be a variable reference of a pointer or procedural type. Assigned(P) corresponds to the test P<> nil for a pointer variable, and @P <> nil for a procedural variable.
Assigned returns false if P is nil, true otherwise.
Note: Assigned can't detect a dangling pointer--that is, one that isn't nil but no longer points to valid data. For example, in the code example for Assigned, Assigned won't detect the fact that P isn't valid.
中文解释:运用Assigned去判断由P引用的指针或过程是否为空,p必需一个引用或指向指针或过程类型的变量,Assigned(P)相当天测试:对指针变量来说,P是否为空;对过程变量来说,@p是否为空。
返回值:P为空,False, p不为空,返回true
Assigned函数在参数不为nil时返回True,表示指针已经指向了某个内存地址,这个内存地址可能是一个对象的首地址,也可能在函数或过程中,声明的一个指针变量,没有赋值为nil,无敌的指向某处。这两种情况,Assigned(指针变量)都不为nil , 函数放回True;而参数为nil时则返回False。
Assigned 并不是一个真正的函数。
技巧:使用 Assigned 的方式來取代直接把参数拿來和nil编辑部,效率会更好。
2.从内存管理方面解释
当你创建一个实例,如SomeComponet.Create(Owner);
系统会有一个指针指向这个实例。
当你释放一个实例时,
系统会将指针指向的东西释放掉,但是指针不是指在相同的位置。
请注意电脑的资源是有限的,所以可能下一步你的程序要跟系统要资源,刚才的指针位置,就出现了其它的资料。
If Assigned(SomeComponet) then SomeComponet := nil;
先检查这个实例有没有在其它地方被设成nil,然后再奖它设成nil。
示例:
if assigned(frm) then frm.close; 但是当下次调用时就会出错。为什么呢?
原因分析:frm.close;frm.free; 只是指定这块内存可以重写,并未释放为NIL。因此当下次调用时即使frm.free已经执行过assigned(frm)仍为TRUE,再次释放 frm.Close 或者 frm.free 肯定会报错;应为frm.Close或frm.free 是释放 对象指针frm 指向的内存空间,在上次已经释放调了,但是 frm 本身并没有 初始化为 nil ,相反它还是指向被释放的内存地址;东西已经没有了,没有地东西去释放,不报错错才怪。
正确的处理方法:
if assigned(frm) then
begin
frm.close;
frm:=nil;
end;
或:
if assigned(frm) then
begin
frm.close;
freeandnil(frm);
end;
万一的例子:
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TForm1 = class(TForm)
Button1: TButton;
Button2: TButton;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
end;
var
Form1: TForm1;
p1: Pointer;
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
var
b1,b2,b3,b4: Boolean;
begin
//p1 := nil;
b1 := Assigned(p1);
GetMem(p1, 1024);
b2 := Assigned(p1);
FreeMem(p1, 1024);//指针p1并没有销毁,只是释放了指针所指向的东西。
b3 := Assigned(p1);
p1 := nil;
b4 := Assigned(p1);
ShowMessageFmt('%s, %s, %s, %s', [BoolToStr(b1,True),
BoolToStr(b2,True),
BoolToStr(b3,True),
BoolToStr(b4,True)]); {False, True, True, False}
end;
procedure TForm1.Button2Click(Sender: TObject);
var
p2: Pointer;
b1,b2,b3,b4: Boolean;
begin
p2 := nil;
b1 := Assigned(p2);
GetMem(p2, 1024);
b2 := Assigned(p2);
FreeMem(p2, 1024);
b3 := Assigned(p2);
p2 := nil;
b4 := Assigned(p2);
ShowMessageFmt('%s, %s, %s, %s', [BoolToStr(b1,True),
BoolToStr(b2,True),
BoolToStr(b3,True),
BoolToStr(b4,True)]); {False, True, True, False}
end;
end.