看看Delphi是怎么做的!,看看Free的源代码!
procedure TObject.Free;
begin
  if Self <> nil then
    Destroy;
end;

解决方案 »

  1.   

    Free是安全的释放,即使已经释放过了
      

  2.   

    对不起,你的问题我回答错了!安全只有在对象指针为nil时有效!
      

  3.   

    use freeandnil replace myobj.free;
      

  4.   

    好像 Assigned()能解决这个问题!
      if not Assigned(MyFormInstance) then
        MyFormInstance:=TMyFormInstance.Create(Application);
      

  5.   

    jump1972(阿飞) 的方法也是不对的,其实Assigned()就等同于 <> nil。
      

  6.   

    谢谢各位
      我没有表达好,我说的更明白一点就是,DELPHI怎么知道一个指针所指向的对象被释放了
    我们能不能做到,是不是释放的内存地址有什么标志
      

  7.   

    TO weenyboy(小公子(戒除游戏,多多罐水))
    检查该指针指向的地址是否被分配,或者该地址的指定地址的属性是否是该类的属性我就是不知怎么检查,请给指点一下谢谢!
      

  8.   

    从dephi本身是没有办法知道的
    也许用操作系统的API可以知道指向的地址不是被分配了,但是我不知道
    释放的内存地址没有什么标志。但是操作系统那边应该有一个可用内存表和分配内存表
      

  9.   

    给一个我自已的东东参考:
    unit yy;interface
    uses Windows, Messages, SysUtils, Forms;function OpenForm(yyForm:TForm):Boolean;implementationfunction OpenForm(yyForm:TForm):Boolean;
    var i:integer;
        FormExist:Boolean;
    begin
     if yyForm=nil then FormExist:=false
     else begin
     FormExist:=false;
     i:=0;
     while (i<= Screen.FormCount-1) do
     begin
      if Screen.Forms[i].ClassType=yyForm.ClassType then
       begin
        FormExist:=true;
        break;
       end;
       i:=i+1;
     end;
     end;
     result:=FormExist;
    end;end.
      

  10.   

    我再试试,看能不能通过API函数实现
    大家继续指点
    我可以再加分
      

  11.   

    标准做法:
    if Assigned(对象) then   
    begin
      对象.free;
      对象:=nil;
    end;可以用Assigned函数可以判断对象是否创建。但是若一个对象被创建了,而且已经被free掉了,
    你用  Assigned(对象) 判断,得到的还是true ,所以要在释放的时候令它为nil ;
    free时,对象是释放了,但变量的指针还是指在老地方(地址),所以,比需用令它为nil 的方法来斩断指针。
      

  12.   

    呵呵,要是这样,我还问什么
    事情是这样:
      如果我把一个对象实体加到一个指针列表里了,然后我释放了这个实体
    即使我把这个实体 =NIL,指针类表对应的指针也并不能等于NIL
    所以访问时会出错.
      vive()说,操作系统那边应该有一个可用内存表和分配内存表,就是这个意思
    有没有可能通过API函数看到某个指针的地址被分配了吗?
      
      

  13.   

    呵呵,要是这样,我还问什么
    事情是这样:
      如果我把一个对象实体加到一个指针列表里了,然后我释放了这个实体
    即使我把这个实体 =NIL,指针类表对应的指针也并不能等于NIL
    所以访问时会出错.
      vive()说,操作系统那边应该有一个可用内存表和分配内存表,就是这个意思
    有没有可能通过API函数看到某个指针的地址被分配了吗?
      

  14.   

    我想说的是:
        free的释放较为安全,而destroy则不可取。
      

  15.   

    不用再提前
    我是这样做的:
    if (Assigned(MyFormInstance)=false) or (MyFormInstance.ComponentCount=0) then
       MyFormInstance:=TMyFormInstance.create(application);
    MyFormInstance.show;
      

  16.   

    myxfang(小方),我说的不是这个意思.
    比如
      glList: TList;
      glform: Tform;
    procedure ss;
    begin
      glList.Add(glform);
       ......
      glForm.Free;
      glForm := nil;
      //此时的glList[0]不是nil
      //但是访问这个指针所指的form却会出错
    end;
    帮忙再看看
      

  17.   

    所以你要加:(Assigned(MyFormInstance)=false)
      

  18.   

    其实Assigned这个函数也只是判断指针是否是nil,
    最好的方法就是每次释放完了以后将它赋值为nil。
    然后以后用Assigned判断。这是一个编程习惯的问题,要养成一个好的编程习惯可以减掉不少麻烦那。
      

  19.   

    FORM1.RELEASE ;
    FORM1:=NIL ;
      

  20.   

    告诉大家Delphi的一个BUG,在Delphi中,用FREE地方法放掉一块内存,其实DELPHI地并没有放掉大家不信可以用你们所知道的任何方法试
      

  21.   

    truezerg(赵明宇) 说的不错,但那不是 bugs,是delphi保证效率的方法之一,该内存能够被delphi 再分配,但并没有将它返回给操作系统
      

  22.   

    同意楼上的,如果你自己不把它赋值为nil根本没有办法确定他有没有被释放掉,因为使用Delphi的内存管理器,他会有自己的内存使用策略,不一定会释放,还给操作系统,即使Delphi释放了,操作系统也不一定真正的回收了,因为Windows(其实所有的都差不多)操作系统是基于页面分配地址的,小块的释放,不一定会被回收,有时(很多时候,你可以试着释放一个动态数据试试,不大的情况下,都不会报告错误)还是可以继续使用的!,当然这变得不可预知了!
      

  23.   

    这样可以吗?
    if form.findcomponent('Edit1') is TEDIT then ...
    if form.findcomponent('Memo1') is TMemo then ...........
      

  24.   

    我觉得没有办法,否则Delphi应该会给一个函数,或者Free方法会判断。
    但是也还是有解决办法的。第一:如果是FORM的话,你可以从Screen中找看有没有它(Screen.Forms);如果是TControl或TComponent的派生类,应该也可以从Application和Screen.Forms顺滕摸瓜找到;
    第二:非常不确切,我似乎从哪本书上看到Delphi有对象管理机制,可能能从这方面入手进行全能的控制;
    第三:如果你非要管理,你可以进行自己一套管理机制,如在Form中增加一个List,其中每一项是变量的地址或你的glList,在赋值时往List中加这些东东,然后在FormDestroy中按照List去掉每一个。如:
    for i:=List.Count-1 downto 0 do
    begin
      if IsVarPtr(List[i]) then
        PTForm(List[i])^ := nil
      else
        TList(List[i]).Remove(Self);
    end;
    甚至还可以这样:
    每个List中的项都存的是事件处理器:
    for i:=List.Count-1 downto 0 do
      TNotifyEvent(List[i])(Self);
      

  25.   

    首先,应该避免你所描述情况的发生才是上策,在写程序时,若这个指针所指向的对象已经释放掉了,同时应该将该指针置空。
    若已经发生了,是不是可以
    function IsValid(APointer :Pointer): Boolean;
    begin
      Result := True;
      try
        引用一下
      except
        Result := False;
      end;
    end;此外,若想知道指向的对象实体是否已经被释放了,需要找些关于Delphi编译的书读,以前听过别人的课,描述了Delphi的内存分配,但现在记不清楚了。大概是一个栈?有时间打开Delphi的system等单元看看(若能看明白)。
      

  26.   


    同意slx_7(稻草人),其实很简单的问题,用一把异常了就不存在了,最直接
      

  27.   

    你是不是说指针为nil值和对象实例被释放时指针的值的不同
      

  28.   

    有几个Windows API: IsBadXXXPtr(),可以检查指针地址的读写权限,大家可以试一下。
      

  29.   

      但是这几个既然是Windows API,我想大概只有对用Windows Memory API进行分配的指针
    结果才准确吧。如果VCL有自己更高层的内存管理机制,那么只能看它有没有提供类似的函数了。
      另外,前面BlueTrees说“即使Delphi释放了,操作系统也不一定真正的回收了,因为”,我想可能是因为运行库的原因,如果不是直接调用Windows API,那么内存的分配
    和释放都是通过运行库进行的,它的内部为了效率也可能实现自己的管理机制。