我有以下代码(我在免费之前检查过objCur不是Nil}:
try
objCur.Free;
Except on E:Exception do
begin
OutputDebugString(PChar('Exception '+E.Message));
Assert(False);
end;
end;
报告此异常消息:
指针操作无效。 objCur是TXX_TEA类型。
objCur:TXX_TEA;
在TXX_TEA.Destroy中我有以下代码
destructor TXX_TEA.Destroy;
begin
OutputDebugString(PChar('Inside Destroy'));
...
inherited;
OutputDebugString(PChar('End of Destroy'));
end;
在debugView中,我看到以下消息:
内部毁灭
...
毁灭结束异常:指针操作无效
我知道objCur.Free调用TXX_TEA.Destroy,但它看起来TXX_TEA.Destroy执行没有错误。那么我应该在哪里跟踪这个无效的指针操作?
答案 0 :(得分:9)
当要求内存管理器释放不属于它的内存时,会发生无效指针操作。
在最外层析构函数返回调用者之前释放对象的内存。在这种情况下,调用者是TObject.Free
。调用inherited
不会导致释放对象的内存,因为编译器知道它不是最外层的调用。
显然,你正在释放一个实际上并不存在的对象,但是这个假定对象的内存内容看起来足够有效,以至于清理对象字段的析构函数中的代码不会崩溃。只有当析构函数完成运行并且对象将被释放时,内存管理器才会检测到该地址没有引用当前分配的任何内容。
答案 1 :(得分:6)
无效的指针操作当你试图释放某些东西时,几乎总是意味着它已经被释放了。如果你想找到哪里,最简单的方法是从SourceForge获取完整版的FastMM。阅读文档,它将向您展示如何将其添加到您的项目以及如何打开FullDebugMode。启用FullDebugMode后,当您尝试释放已经释放的内容时,它将使用一个对话框中断程序,该对话框为您提供了第一次释放对象时的堆栈跟踪。这应该可以帮助您跟踪错误。
答案 2 :(得分:3)
很可能你仍然有一个对它的引用,并且一些代码在释放后使用该引用来访问该对象。这可以是对象引用或接口引用(非nil的接口引用将在作用域末尾调用_Release)。
我们必须看到更多代码才能真正找出导致它的原因。