procedure TForm1.Button1Click(Sender: TObject);
var
  Bitmap : TBitmap;
begin
  Bitmap := TBitmap.Create;
  Bitmap.Free;
  Bitmap.Canvas.MoveTo(10,10);   //这个语句为什么不发生错误呢?对象已经释放掉了啊
end;procedure TForm1.Button1Click(Sender: TObject);
var
  Bitmap : TBitmap;
begin
  Bitmap := TBitmap.Create;
  Bitmap.Canvas.MoveTo(10,10);  //这里加了这么一句,最下面的语句就会报错,请高手帮忙讲解一下
  Bitmap.Free;
  Bitmap.Canvas.MoveTo(10,10);
end;

解决方案 »

  1.   

    1楼的朋友,我在DELPHI7和delphi2007测试均不报错,请您再帮忙测试一下?
      

  2.   

    的确如此啊,但是destroy方法中说会自动释放canvas的,不明白
      

  3.   

    不光是这个TBitmap的对象,我想其他对象也是一样的
      

  4.   

      Bitmap.Canvas.MoveTo(10,10); 
      ShowMessage(Bitmap.ClassName);//加一句你就看出问题来了
      

  5.   

    请10楼的朋友找个我猜想的类,给我测试下OK?
    9楼的朋友,我加这句,结果是TBitmap,没看出什么,请你指点一下?
      

  6.   

    procedure TForm1.Button1Click(Sender: TObject);
    var
      StrList : TStringList;
    begin
      StrList := TStringList.Create;
      StrList.Free;
      StrList.Add('asdf');
      ShowMessage(StrList[0]);
    end;
    这里还可以显示出来,很不解
      

  7.   

    请参考一下VCL 的代码
    procedure TObject.Free;
    begin
    if Self <> nil then
    Destroy;
    end;
    用FreeAndNil释放对象是比较标准的做法
      

  8.   

    procedure TForm1.Button1Click(Sender: TObject);
    var
      StrList : TStringList;
    begin
      StrList := TStringList.Create;
      StrList.Free;
      StrList.Add('asdf');
      ShowMessage(StrList[0]);
    end;
    这里还可以显示出来,很不解12楼的朋友,我试过了啊,这段代码不行啊,D7试验的
      

  9.   

    没啥奇怪的,Delphi就这样
    FreeAndNil是替代Free用的,Inside vcl好象有一处讲过这个问题
      

  10.   

    他这里不是问对象释放后为什么要置nil才能判断对象不存在的问题,FreeAndNil只是Free + Nil而已,在释放内存上是等效的。他是在问为什么强行访问依然不出错,这方面应该从内存管理上来解释。不过反正我这边是出错的,不出错的绝对只是偶然,不然这个FREE有啥用。
      

  11.   

    第一次不出错:var bitmap: TBitmap;
    定义了一个变量引用,bitmap.free执行以后,bitmap引用的那个对象被释放了,但是bitmap指向的方法指针依然存在(Button1Click方法执行完成后,这些东东才全部不存在)
    bitmap.canvas.moveto()调用的时候,canvas对象没有被创建,见TBitmap.GetCanvas方法,又创建了一个Canvas对象并赋值给FCanvas,然后在执行Canvas.moveto方法,这是没有问题的。第二次出错:
    执行bitmap.canvas.moveto,实际上Tbitmap中的私有属性FCanvas已经赋值,当执行bitmap.free(见TObject.free)时,FCanvas对象被释放了,然后第二个bitmap.canvas.moveto执行时,Canvas对象,这里通过getCanvas方法引用了FCanvas属性,这个FCanvas属性已经释放了,所以再调用moveto方法就出现关键字错误了。出错时由于TBitmap的私有属性FCanvas引起的。