当第二次执行如下代码时,在标注了的地方出现非法内存操作。跟踪进去看cpu信息,发现它抛出了一个异常,大家帮忙看看。(另一段也是按钮打开这个打开文件对话框,没有问题)procedure TForm1.Button3Click(Sender: TObject);
var
  TempleteName:TStringList;
  i           :integer;
begin
  TempleteName := TStringList.Create;  if OpenDialog1.Execute then       //当点第二次时就在这里出现非法内存操作
  begin
    TempleteName := (OpenDialog1.Files) as TStringList;
    if TempleteName.Count <> 0 then
    begin
      for i := 0 to TempleteName.Count -1 do
        TreeView4.Items.Add(nil,ExtractFileName(TempleteName[i]));
    end;
  end;
  TempleteName.Free;
end;

解决方案 »

  1.   

    TempleteName将opendialog1给FREE掉了,它们指向同一对像...
      

  2.   

    同意gzyzljk(正龙剑客)
    TempleteName := () as TStringList;
    ////
    try;
    TempleteName.Assign(OpenDialog1.Files) ;
      

  3.   

    程序我看了一天了,本身没有什么问题。也新开了一个project试,就没有出现。Drate(鸟窝里的虫) :找不到理由,呵呵,但它确实出现了。gzyzljk(正龙剑客) :TempleteName在free时,只会free自己吧,我把它按值复制再看看。xirumin(吃好喝好) :我的在退出时也有问题。看来的确是Free掉了不该Free的东西。大家再看看还有什么原因。
      

  4.   

    谢谢outer2000(天外流星)与gzyzljk(正龙剑客)
    改成Assign赋值就没有问题了。看来 TempleteName := (OpenDialog1.Files) as TStringList;这样用是不对的。的确是指象了OpenDialog1这个对像。谢谢各位,回头我再补补VCL知识。
      

  5.   

    TempleteName := (OpenDialog1.Files) as TStringList;
    很明显的,你把OpenDialog1对象的一块内存区域指针赋值给了TempleteName
    而后你有调用TempleteName.Free释放该内存空间的的这个TStringList对象
    这个对象是OpenDialog1内含的,当第2次调用OpenDialog1.Execute 时,OpenDialog1要访问该TStringList,但是此时该对象已经被你释放掉了,当然出错了。
    把TempleteName := (OpenDialog1.Files) as TStringList;
    改为:
    TempleteName.Assign(TStringList(OpenDialog1.Files));
      

  6.   

    错了,根本不用强制转换
    TempleteName.Assign(OpenDialog1.Files);
      

  7.   

    procedure TForm1.Button3Click(Sender: TObject);
    var
      TempleteName:TStringList;
      i           :integer;
    begin
     if OpenDialog1.Execute then       //当点第二次时就在这里出现非法内存操作
      begin
        TempleteName := (OpenDialog1.Files) as TStringList;
        if TempleteName.Count <> 0 then
        begin
          for i := 0 to TempleteName.Count -1 do
            TreeView4.Items.Add(nil,ExtractFileName(TempleteName[i]));
        end;
      end;
    end;
      

  8.   

    不用TStringList也行
    var
    //  TempleteName:TStringList;
      i           :integer;
    begin
    //  TempleteName := TStringList.Create;  if OpenDialog1.Execute then       //当点第二次时就在这里出现非法内存操作
      begin
     //   TempleteName := TStrings(OpenDialog1.Files);
        if OpenDialog1.Files.count <> 0 then
        begin
          for i := 0 to OpenDialog1.Files.Count -1 do
            TreeView4.Items.Add(nil,ExtractFileName(OpenDialog1.files[i]));
        end;
      end;
      

  9.   

    pazee(耙子) 老大真搞笑,把我的那句Free删掉完事了。:-)
      

  10.   

    var
      TempleteName:TStringlist;
      i           :integer;
    begin
      TempleteName := TStringlist.Create;
      if OpenDialog1.Execute then       //当点第二次时就在这里出现非法内存操作
      begin
       try
     TempleteName.AddStrings(OpenDialog1.Files);
        if TempleteName.Count <> 0 then
        begin
          for i := 0 to TempleteName.Count -1 do
            TreeView4.Items.Add(nil,ExtractFileName(OpenDialog1.Files[i]));
        end;
      finally
      TempleteName.Free;
      end;
      end;
    end;
      

  11.   

    to 无名:
    不是高效,  TempleteName := TStringList.Create;
      ....
      TempleteName := (OpenDialog1.Files) as TStringList;这两句的结果势必会造成内存泄漏!TStringList.Create这代码申请的内存你给弄丢了。
      

  12.   

    to zwjchina(蒲石)  把OpenDialog1对象的一块内存区域指针赋值给了TempleteName  //一块内存区域指针你指的是不是OpenDialog1对象的一部分内存区域指针