var  
   Form6:  TForm6;  
   test:Array  of  TButton;  
   num:integer;           //动态数字
implementation  
 
{$R  *.dfm}  
 
procedure  TForm6.Button1Click(Sender:  TObject);  
var  
       i:integer;  
begin  
       num:=StrToInt(edit1.Text);//获取要动态生成组件的数目  
       setLength(test,num);  
       for  i  :=  0  to  num-1  do  
       begin  
               test[i]:=TButton.Create(self);//动态生成组件  
               test[i].Parent:=form6;  
               test[i].Left:=130*i;  
       end;  
end;  
.......  
 
procedure  TForm6.FormClose(Sender:  TObject;  var  Action:  TCloseAction);  
var  
       i:integer;  
begin  
       for  i  :=  0  to  num-1  do  //释放内存  
       begin  
       test[i].Free;  
       end;  
end;  
 
 
为什么每次关闭窗口的时候就报错:  
project1.exe  raised  exception  class  EAcessViolation  with  message  'Access  violation  at  address  00492FC3'  in  module  project1.exe'.  write  of  address  00000004  
 
大家帮看看,谢谢

解决方案 »

  1.   

    for  i  :=  0  to  num-1  do  //释放内存  老问题了.删除列表的时候要从最后一个开始.for  i  :=  num-1  downto  0  do  
    test[i].Free;
      

  2.   

    用TObjectList 代替 Array更好TButton.Create(self);如果指定OWNER 是 SELF ,则在关闭时不用一个个的释放。TForm6 会帮你释放的。仅让 setLength(test,0);test=null; 就可以了。
      

  3.   

    test:Array  of  TButton;  
       num:integer;最好不要定义成全局变量。
      

  4.   

    //for  i  :=  0  to  num-1  do  //释放内存  老问题了
    楼上的回复好象有点仓促了吧, 因为 num 不是 ComponentCoun或ControlCount. 
    我测试了上面代码没有问题的(虽然不是很规范). 请LZ看看你的其他代码.
      

  5.   

    谢谢大家的帮助,可是更奇怪的问题是,我在另外一台机器上重新写了一个测试,却一点问题都没有。而且也没有写释放的代码;
    unit Unit1;interfaceuses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, StdCtrls;type
      TForm1 = class(TForm)
        Edit1: TEdit;
        Button1: TButton;
        procedure Button1Click(Sender: TObject);
      private
        { Private declarations }
      public
        { Public declarations }
      end;var
      Form1: TForm1;
      Test:Array of TButton;
    implementation{$R *.dfm}procedure TForm1.Button1Click(Sender: TObject);
    var
        i,num:integer;
    begin
         num:=StrToInt(edit1.Text);//获取要生成的组件个数
         setLength(test,num);
         for i := 0 to num-1 do  //动态生成组件
         begin
           Test[i]:=TButton.Create(self);
           Test[i].Parent:=Form1;
           Test[i].Left:=i*130;
         end;
    end;end.
    而在原来那台机器上面,如 ZyxIp(绝望中...) 所说,加入:
    procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
    begin
        setLength(test,0);
        test:=nil;
    end;
    运行没问题,关闭窗口的时候,有时候可以,有时候还是出错。
      

  6.   

    下面这样处理是错误的,FormClose只是隐藏,对象没释放,却把数组释放了.
    procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
    begin
        setLength(test,0);
        test:=nil;
    end可改为:
    procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
    var
      I: Integer;
    begin
      for I := Low(test) to High(test) do
      begin
        Test[I].Parent := nil;
        Test[I].Free;
      end;
      setLength(test,0);
    end
      

  7.   

    procedure  TForm6.FormClose(Sender:  TObject;  var  Action:  TCloseAction);  
    var  
           i:integer;  
    begin  
           for  i  :=  0  to  num-1  do  //释放内存  
           begin  
           test[i].Free;  
           end;  
    end;  
     
    这一段不需要的,自动会free的!
    ------------------------------------
    矢量图形组件http://www.codeidea.com