在 aControl 内部调用 aControl.free
阅读此后我想知道下一个代码有什么问题:
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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
在该例程上放置一个断点并检查调用堆栈。从事件处理程序返回后,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.
该代码是最严重的错误,因为它在 99.99% 的情况下都不会暴露出来。
当 VCL 假定该对象存在时,您释放一个对象(按钮控件)。实际发生的情况是对象的内存被释放,但尚未重用,因此上面的代码可以正常工作,就好像对象尚未释放一样,但它仍然是一个错误。
以下简单的错误说明了这种情况:
您可以测试上面的代码,它应该按预期工作,因为
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:
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.