UNIT1中创建FOMR2
procedure TForm1.Button1Click(Sender: TObject);
begin
form2:=Tform2.Create(nil);
form2.Show;
end;释放FORM2
procedure TForm1.Button2Click(Sender: TObject);
begin
form2.Free;
end;我以前的理解是这样的,不知道对不对:FORM2是个指针,Tform2.Create(nil);这句代码的作用就是申请一块内存空间,然后把申请到的空间的首地址传给FORM2。如果连续执行BUTTON1中的代码,然后再执行BUTTON2中的代码,就只能够释放FORM2。由于FORM2中始终指向的是最后一次创建的窗体的地址。之前申请到的空间就被丢掉了,这就会造成内存泄露。但我今天测试了一下,发现好象不是这样的。我在FORM1中连续点击BUTTON1,创建一系列的FORM2。然后再点BUTTON2释放掉FORM2。发现释放掉的其实是最后一次创建的FORM2。而且每次点BUTTON1创建出来的FORM2的NAME属性都不一样,按照FORM2 FORM2-1 FORM2-2 FORM2-3.....的顺序依次递增。所以点BUTTON2后,释放的并不一定是FORM2,而是最后一次创建的FORM2的副本。
我现在越来越糊涂了,搞不明白form2:=Tform2.Create(nil);这句代码到底执行了什么过程。为什么创建出来的窗体名称竟然不是FORM2? 请各位高手给我讲讲form2:=Tform2.Create(nil);这句代码的底层实现细节。它究竟做了那些操作,是不是有什么内存分配表记录这些创建的对象呀?

解决方案 »

  1.   

    >>form2:=Tform2.Create(nil);Tform2.Create(nil)就是创建一个窗口,说白了也就是一段内存,然后,Form2就是指向这块内存的指针,即可以通过fomr2来使用这个窗口问题在于,如果form2已经指向了一块内存,却又再调用form2:=Tform2.Create(nil)一次的话,form2就是指向新的一段内存,原来的那一块就丢掉了,造成内存泄露也就说,最后一次from2.free,也指释放最后一次创建的窗口这样就可以解释你上面说的情况了
      

  2.   

    为防止这种情况,大家一般都是这么做的//创建
    if  not Assigned(form2) then
      form2:=Tform2.Create(nil);form2.show();
      
    //释放
    freeAndNil(form2);
      

  3.   

    我不是问这种问题的解决办法,这种方法我经常用的,关键现在在一个MDI窗体中要对一个窗体重复创建,我以前概念不太清楚,所以总觉得这样会有问题.但今天想了下应该可以的.重复创建的窗体都是合法的窗体,都可以进行操作,不会报内存错误,因为他们每次创建后的名字都是不一样的.例如:FORM1-1 ,FORM1-2.... 至于内存泄露可以在CLOSE事件中置ACTION=ACFREE.这样就可以了。只不过我还是不太懂DELPHI内部对象CREATE的过程,以及他执行的操作.
      

  4.   


    你理解的没问题
    但Form.Name和变量名没任何关系《〈〈〈〈〈〈〈〈
    A := TForm2.Create(nil); // 并不代表创建后的实例Name属性名位'A'
    否则
    B := A;
    C := A;
    是不是会出现多个Name?它们都是同一个实例指针
    元件的Name是不能重复的TForm的Name属性是保存在dfm窗体文件中的,读取的时候就会执行下面的语句
    多看VCL源代码你会明白得更透彻
    //Classes.pas
    function TReader.ReadRootComponent(Root: TComponent): TComponent;  function FindUniqueName(const Name: string): string;
      var
        I: Integer;
      begin
        I := 0;
        Result := Name;
        while not IsUniqueGlobalComponentName(Result) do
        begin
          Inc(I);
          Result := Format('%s_%d', [Name, I]);
        end;
      end;
    //................
      

  5.   

    CREATE执行如下工作:
    分配内存,初始化内存,设定执行框架。
    分配内存:在内存中申请 类Tform2 大小的空间(具体到Tform2的每一个变量,函数地址,VMT等等)
    初始化内存:所有变量的内存空间全置为0
    设定执行框架:告诉系统form2的内存防问范围(姑且这么说)在执行form2:=Tform2.Create(nil);之前
    form2只是一个Tform2类型的指针而已!再具体的是  看李维的  Inside VCL  在第二章讲的很简单容易理解
      

  6.   

    多谢  zswang(伴水清清)(专家门诊清洁工) ( ) 
          do2008(事情做了,才是事情) 
          moklee(mok) 现在有点明白了.
      

  7.   

    to zswang(伴水清清)(专家门诊清洁工)
    你DELPHI用了6年了吧?以前老是比较迷茫,不直到还该不该坚持DELPHI.但现在看到你的回复,感觉不浮躁了。还是把技术学扎实再说吧.你是我的偶像.喉喉