在 aControl 内部调用 aControl.free

发布于 2024-10-27 08:44:50 字数 255 浏览 5 评论 0原文

阅读后我想知道下一个代码有什么问题:


procedure TForm1.Button5Click(Sender: TObject);
begin
  Button5.free;
end;

After reading this I would like to know what is the problem with the next code:


procedure TForm1.Button5Click(Sender: TObject);
begin
  Button5.free;
end;

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

梦里泪两行 2024-11-03 08:44:50

在该例程上放置一个断点并检查调用堆栈。从事件处理程序返回后,Button5 中的代码仍然在运行,并且其他 VCL 代码预计 Button5 仍然存在。如果您从其下方删除该对象,则很可能最终会损坏内存或以某种方式引发异常。

如果您想这样做,正确的方法是调用 PostMessage 并向表单发送一条消息,该消息最终将在当前代码运行完成后安全地释放对象。

Put a breakpoint on that routine and examine the call stack. Once you return from the event handler, there's still code from Button5 running, and other VCL code that expects Button5 to still be around. If you delete the object out from under it, there's a good chance that you'll end up corrupting memory or raising exceptions somehow.

If you want to do this, the correct way is to call PostMessage and post a message to the form that will end up freeing the object safely after the current code is finished running.

你在我安 2024-11-03 08:44:50

该代码是最严重的错误,因为它在 99.99% 的情况下都不会暴露出来。
当 VCL 假定该对象存在时,您释放一个对象(按钮控件)。实际发生的情况是对象的内存被释放,但尚未重用,因此上面的代码可以正常工作,就好像对象尚未释放一样,但它仍然是一个错误。

以下简单的错误说明了这种情况:

type
  PData = ^TData;
  TData = record
    Value: Integer;
  end;

procedure NastyBug;
var
  P: PData;

begin
  New(P);
  P^.Value:= 2;
  Dispose(P);
// nasty buggy code
  ShowMessage(IntToStr(P^.Value));
  P^.Value:= 22;
  ShowMessage(IntToStr(P^.Value));
end;

您可以测试上面的代码,它应该按预期工作,因为 P 的已释放内存尚未重用,但该代码是一个明显的错误。

The code is a worst kind of a bug because it does not reveal itself in 99.99% of cases.
You free an object (button control) while VCL assumes the object exists. What actually happen is that the object's memory is freed, but not reused yet, so the above code will work OK, as if the object was not freed yet, but still it is a bug.

The following simple bug illustrates the situation:

type
  PData = ^TData;
  TData = record
    Value: Integer;
  end;

procedure NastyBug;
var
  P: PData;

begin
  New(P);
  P^.Value:= 2;
  Dispose(P);
// nasty buggy code
  ShowMessage(IntToStr(P^.Value));
  P^.Value:= 22;
  ShowMessage(IntToStr(P^.Value));
end;

You can test the above code and it should work as expected, because the disposed memory for P is not reused yet, but the code is a clear bug.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文