【问题标题】:Access violation when freeing TBitmap variable -- Bitmap variable still assigned after freeing? [duplicate]释放 TBitmap 变量时访问冲突——释放后仍分配位图变量? [复制]
【发布时间】:2017-04-22 18:12:27
【问题描述】:

我在 VCL 表单应用程序中有此代码:

implementation

{$R *.dfm}

var
  MyBitmap: TBitmap;

procedure TFormMain.FormCreate(Sender: TObject);
begin
  MyBitmap := TBitmap.Create;
end;

procedure TFormMain.FormDestroy(Sender: TObject);
begin
  if Assigned(MyBitmap) then
    MyBitmap.Free;
end;

procedure TFormMain.Button1Click(Sender: TObject);
begin
  if Assigned(MyBitmap) then
    MyBitmap.Free;
end;

当我第二次单击按钮时,我在按钮的单击处理程序中的MyBitmap.Free; 中遇到访问冲突。但是MyBitmap 在第一次单击按钮后不应再分配。那么为什么if Assigned(MyBitmap) then 条件在第一次按钮点击时显然对第二次按钮点击不起作用?

Delphi 10.1 柏林更新 2

【问题讨论】:

  • Assigned 检查是否等于 nil,释放对象引用不会使其为零。因此,您正在尝试双重免费。
  • 看来System.SysUtils.FreeAndNil(MyBitmap) 可以在没有 AV 的情况下完成这项工作。
  • 因此,我们最终了解到:可以使用FREE 释放对象,并且可以将对象变量设置为NIL,反之亦然。这是正确的吗?
  • MyObject.Free 执行时到底发生了什么?对象的内存是否显式释放?具体是如何发布的?这在实践中意味着什么?
  • 实际上你可以说释放负责释放为对象获取的资源,包括内存。

标签: delphi free delphi-10.1-berlin tbitmap


【解决方案1】:

Assigned 函数只检查指针是否为Nil。它不会检查它是否指向现有对象。您需要在释放它后将其设置为Nil,以使Assigned 函数按预期工作。 FreeAndNil 执行两条指令。

【讨论】:

  • 释放对象变量时,何时使用Free,何时使用FreeAndNil,是否有共同的规则?
  • @user - 如果有可能一个对象可以从多个位置释放,FreeAndNil 会很有用。但这并不常见。
  • 这是基于意见的。恕我直言,您应该在释放引用的对象后可以访问变量时将对象引用设置为Nil。因此,当Free 之后没有任何事情发生时,您不需要在方法中使用Nil 局部变量。之后没有人可以访问这些变量。这同样适用于存储在类的成员变量中并在其析构函数中释放的对象引用。但是,当您在该对象的生命周期内Free它们时,您应该额外Nil它们(例如,在单击按钮时释放表单的成员)。
猜你喜欢
  • 2011-10-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-01-03
  • 1970-01-01
  • 2011-05-03
  • 2013-06-20
  • 1970-01-01
相关资源
最近更新 更多