本帖最后由 sandok 于 2009-08-24 11:15:54 编辑

解决方案 »

  1.   

    type
      TForm1 = class(TForm)
        Label1: TLabel;
        Label2: TLabel;
        Label3: TLabel;
        Button1: TButton;
        procedure Button1Click(Sender: TObject);  private
        { Private declarations }
      public
        { Public declarations }
        mystrlist:Tstringlist; //不是放在这里的问题..看下面..
      end;var
      Form1: TForm1;implementation
    procedure TForm1.Button1Click(Sender: TObject);
    var
      mydata:TMydata;  
      mystrlist:Tstringlist;
    begin   mydata.create;
       mystrlist:=TStringList.Create;  //没有create所以出错..
       mystrlist:=mydata.Getdata('test.txt');    Label1.Caption := mystrlist[0];
       Label2.Caption := mystrlist[1];
       Label3.Caption := mystrlist[2];     mystrlist.free; 
    end;end.
      

  2.   

    不create ,没有问题,我运行没有问题 TMydata.Getdata 已经给create了
    看这个教程:
    如果一个函数返回的对象不是我们经常使用的integer,string..而是Tstringlist、Tbutton等object那怎么办呢?
    为什么会有这个问题,因为函数的result是一个object,按照object pascal要求,是需要其owner释放(free)。
    举例:
     
    function GetStringList: TStringList;
    begin
      result := TStringList.Create;
      result.Add('an item') ;
    end;
     
    以上面的函数中,是没有释放result的。那会不会造成“leak Memory”呢?
    文中的作者提醒,只要调用后,进行释放就可以了。
     
    var
      sl : TStringList;
    begin
      sl := GetStringList;//sl指向GetStringList的内存,因此后面释放sl,相当释放了GetstringList函数内部申请的内存。
      try
        ShowMessage(sl[0]) ;
        // or something like
        // ListBox1.Items.Assign(sl) ;
      finally
        sl.Free;
      end;
    end;
      

  3.   

    type
      TMydata = class
        private      //FAllnum:Integer;  //FAllnum声明放在这里就出错;//如果你在其他地方非本类或同单元子类调用就会出问题。在当前类中不会出问题。
        protected
            FAllnum:Integer;  
        public
          Function Getdata (const Filename   : String):Tstringlist;  end;implementation
       Function TMydata.Getdata(const Filename : String):Tstringlist; 
       begin
         Result:=Tstringlist.Create;
         Result.LoadFromFile( ExtractFilePath(Application.ExeName) + Filename);     FAllnum:=Result.Count; //为什么FAllnum的声明放在private里,这句就会出错呢: access 
    这里不会出问题,还有一点,我们不推荐使用这种方式,不易查看,也不宜调试
    exception   end;
    end.全局变量只要放在接口部分,就是全局的。
      

  4.   

    但是,我把FAllnum:Integer;放在private 里后,
    调用时一点Button1, 就出现
    Debugger Exception Notification  
    Access violation at address 00403EDB放在protected里就没事,为什么啊?
      

  5.   

    忘了说了 把FAllnum:Integer;放在private 里后, 
    调用时没问题,但关闭窗体后,就出现  
    Access violation at address 
      

  6.   

    楼主你说的,我看都没有问题
    倒是下面调用的方法里有问题procedure TForm1.Button1Click(Sender: TObject);
    var
      mydata:TMydata;  
      mystrlist:Tstringlist;
    begin  mydata := TMydata.create;        //应该这样创建
      try
        mystrlist:=mydata.Getdata('test.txt'); 
        try      Label1.Caption := mystrlist[0];
          Label2.Caption := mystrlist[1];
          Label3.Caption := mystrlist[2];
        finally
          mystrlist.free;
        end;
      finally
        mydata.free;      //增加释放mydata
      end;
    end;
      

  7.   

    果然改成 mydata := TMydata.create; 问题全没了!