关于Assigned的用法

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.

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值