在一个SHOW的窗体CLOSE的事件中,
用FreeAndNil(窗体);时,报错
如果用 Action:=CanFree;
       Form:=nil;
     就不会错,
能否详细说说,谢谢

解决方案 »

  1.   

    FreeAndNil(窗体): 在事件中不能销毁,因为事件是在消息处理中调用的,在事件后还有很多代码需要窗体对象。Action := CanFree: 告诉窗体的事件处理方法,在消息处理结束后销毁窗体对象;
    Form:=nil:仅仅是将一个变量置为空指针,但对象并没有被销毁。
      

  2.   

    漏了一句,
    Form:=nil;
    Form.free;也没有问题,
    <quote>
    在事件后还有很多代码需要窗体对象。</quote>
    是指系统的调用吗?
      

  3.   

    agui(阿贵 as 光明山人
    正确的Form:=nil;
    Form.free;
    是没有意义的,Nil没有Free的,执行上不会出错,但Form的真实对象没有被释放的
    这样地导致内存漏洞的
      

  4.   

    Free方法不会自动把对象设为Nil,所以在调用Free后最好手动把对象设为NIl,做到这一点的一个简单方法是调用FreeAndNil过程。
    globalVar:=TNewClass.create;
    try
    Globalvar.over;
    finally
    FreeAndNil(globalvar);
    end;
      

  5.   

    漏了一句,
    Form:=nil;
    Form.free;
    你的这句free的并不是原来的form指向的那个窗体了,因为你调用了Form:=nil;使程序与这个窗体的内存失去了联系-“内存泄漏”
    正确的释放方法就像楼上的所说。
    不知道我说的对否
      

  6.   

    借鉴一下高手的说法吧:
    procedure TObject.Free;
    asm
            TEST    EAX,EAX
            JE      @@exit
            MOV     ECX,[EAX]
            MOV     DL,1
            CALL    dword ptr [ECX].vmtDestroy
    @@exit:
    end;
    Free= if Object is not nil then destory else do nothing.
    在destory之后,对象所占用的空间被释放了,但是对象变量的值(就是指向对象实例空间的指针)
    并没有被清空,如果对同一个对象进行两次Free,就极可能发生内存访问错误。下面是一个例子:
    procedure TForm1.q34(Sender: TObject);
    var
      a:TStringList;
    begin
      a:=TStringList.Create; //对象获得实例空间
      //a.Free;    //1
      FreeAndNil(a); //2  如果让1有效而2无效,则会在3处出先非法内存访问错误,因为此时
      //a所指向的内存已经不再属于对象
      a.Free; //3
      a.Destroy; //出错——试图释放一个空对象
    end;