FastMM4说,"这块头已经被破坏"
-
12-09-2019 - |
题
我有这个讨厌的错误,消失在过去的但是现在经过相当长的一段时间,它返回。
我有两个斩对象(来自TPersistent)创建并装入TAsmJob目(来自TObjectList).
在运行、形成创建了一个TStringGrid然后AsmJob它创建了那两个山姆对象(及载的某些数据从磁盘在每个)。该AsmJob也被分配到网格。当时的形式被销毁,格需要照顾的AsmJob通过释放,释放的斩的对象。这里的问题是:第一个目的是释放withot问题,但是第二个死的时候它的继承法(在摧毁析构)。
我用FreeAndNil在整个程序的,免费的对象。该斩对象不是零!!!!!所以,这是第一次尝试是免费的对象。甚至里面的数据的对象是一致的。
骨干的程序看起来像这样:
**Create:**
Form -> StringGrid
-> AsmJob -> Sam1, Sam2
StringGrid.AsmJob:= AsmJob;
**Free:**
Form -> StringGrid -> AsmJob -> Sam1, Sam2
我真的不明白我试着双免费或复盖的对象之后已被释放。
编辑:
一些错误。我得到了:
FastMM已检测到一个错过一个 免费的框扫描操作。FastMM 检测到一块已 修改后被释放。
FastMM已检测到一个错过一个 免费的框扫描操作。块 头已经被破坏。
详细说明:
The current thread ID is 0x19C, and the stack trace (return addresses) leading to this error is:
402E77 [System][@FreeMem]
4068DC [System][@DynArrayClear]
405E2D [System][@FinalizeArray]
405D31 [System][@FinalizeRecord]
40432F [System][TObject.CleanupInstance]
404272 [System][TObject.FreeInstance]
404641 [System][@ClassDestroy]
4D313E [UnitSam.pas][TSam.Destroy][297]
4042BF [System][TObject.Free]
4149ED [SysUtils][FreeAndNil]
4D9C0A [UnitAsmJob.pas][UnitAsmJob][TAsmJob.Destroy][180]
我有所有的"调试"选项,启用了在IDE,包括"范围内检查"。此外,FastMM4设置的超级积极的调试模式。没有FastMM或外部的调试该计划运行得很好-但我知道这并不意味着错误是不存在了。实际上,它的工作(可能)对于超过一个一年,直到我已经安装FastMM.
编辑:
感谢大家。没有我觉得我动了一下,在良好的方向。
该方案的结构更加复杂我只提供骨干,以保持原有的员额小。但是什么,它已经得到了较大:) 因此,这些斩对象是用来装载数据从磁盘。一个文件在每个对象。他们正在做的也有一些处理和数据验证。对于每个这些斩我也有一个图形象,显示在屏幕上(图)中包含的数据斩的对象。每个线在TStringGrid也显示的数据,在斩,但文字上.
一个问题我有:如果我休息的程序在更小的碎片找出其中的错误,误差仍然会出现?或者,它可能只出现在这个特别的配置?
回答"如何AsmJob获得分配给TStringGrid使TStringGrid破坏AsmJob,你能告诉我们?"
MyGrid = TStringGrid
public
AsmJob: TAsmJob;
end;
然后在某处在TForm.Create(形式持有的电网),我做的
MyGrid.AsmJob=AsmJob;
和在析构的MyGrid我做的事:
begin
FreeAndNil(AsmJob);
inherited
end;
解决方案
这个错误意味着你损坏了代码存储器内部管理结构。你的电话叠表示点,当毫米检测到这一点。这不是错误的道路,或任何相关的。实际错误发生之前这一刻。它可能会或可能不相关提到的课程。
你也可以打开FullDebugModeScanMemoryPoolBeforeeveryoperation全球变量,来获得一个错误后,几乎立即的问题发生,但此项减慢你的执行很多。
可能是最好的选择就是呼叫ScanMemoryPoolForCorruptions周期性。叫它在一个地方。有一个错误?叫它早。还有一个错误?叫它迟早的一次。没有错误?你的问题坐的地方之间的最后一个电话。现在你可以使用FullDebugModeScanMemoryPoolBeforeeveryoperation变得精确位置。只是打开它只有在这个码的区域,并把它关掉的权利之后。
有一个非常类似的错误:"FastMM检测到一块已经被修改之后被释放".在这种情况下你的代码修改不是内部结构,但是其他的记忆,它并不是在所有使用("免费存储器").
顺便说一句,你的错不是双免费的!如果这是一个双免费电话,FastMM会告诉你,明确(很容易检测,因为你是想要免费的不使用或不存存储块):"企图已经取得了免费/重新分配未分配块"。
其他提示
一个块头损坏通常意味着有些东西被复盖的存储器,通常通过这样做的某种不安全的操作。你使用原指针或大会的代码,在任何任务?还有,如果你有范围内的检查和关闭边界检查,试图把它们在和重建。他们可以帮助捕获大量此类的问题。
可能有逻辑的比赛中的某处的代码在哪里的对象是正在写,因为它是被释放。加空检查和其他IPC机制(锁定列表等等),以确保不是这种情况。
另一个选择可以是子类代码添加记录了--并检查对象是否正在依次访问。
一对夫妇的事情和我在问因为我看不到你的代码。
给出下列代码:
procedure TForm1.FormCreate(Sender: TObject);
var
wObjLst : TObjectList;
begin
wObjLst := TObjectList.Create;
try
wObjlst.OwnsObjects := true;
wObjlst.Add(TPersistent.Create);
wObjlst.Add(TPersistent.Create);
finally
freeandnil(wObjlst);
end;
end;
这适用出错误。
你的状态,
在运行、形成创建了一个TStringGrid然后将其AsmJob 创建这两个山姆对象(及载的某些数据从磁盘中每一个的 他们)。该AsmJob也被分配到网格。当时的形式被破坏, 格需要照顾的AsmJob通过释放,释放的斩 对象。这里的问题是:第一个目的是释放withot问题 但第二个去世时,其继承法(在摧毁 析构)。
我的第一个问题是如何AsmJob获得分配给TStringGrid使TStringGrid破坏AsmJob,你能告诉我们?
第二,为什么要创建一个后裔的TObjectList得到它存储的两个对象然后免费免费,而不是他们的创造他们自己和让TObjectList摧毁他们如上所示。
其他东西尝试是以下载完整FastMM4包 fastmm.sourceforge.net, 安装和使用fulldebug dll追查出究竟是什么样的对象是失败的。你和我假设它是一个山姆对象,它可能会或可能不是。