加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

delphi – FastMM4说“块头已被破坏”

发布时间:2020-12-15 09:50:06 所属栏目:大数据 来源:网络整理
导读:我有这个令人讨厌的虫子在过去消失了,但现在经过一段时间它又回来了. 我有两个TSam对象(派生自TPersistent)创建并加载到TAsmJob对象(从TObjectList派生). 在运行时,表单创建一个TStringGrid,然后创建AsmJob,它创建这两个SAM对象(并从每个对象的磁盘加载一些
我有这个令人讨厌的虫子在过去消失了,但现在经过一段时间它又回来了.

我有两个TSam对象(派生自TPersistent)创建并加载到TAsmJob对象(从TObjectList派生).

在运行时,表单创建一个TStringGrid,然后创建AsmJob,它创建这两个SAM对象(并从每个对象的磁盘加载一些数据). AsmJob也被分配给网格.
当表单被销毁时,Grid通过释放它来处理AsmJob,从而释放TSam对象.这是问题所在:第一个对象没有问题,但第二个对象在调用其继承方法(在Destroy析构函数中)时会死掉.

我在整个程序中使用FreeAndNil来释放对象. TSam对象不是NIL !!!!!所以,这是第一次释放对象的尝试.甚至对象内部的数据也是一致的.

该计划的主干如下:

**Create:**

Form -> StringGrid
     -> AsmJob -> Sam1,Sam2
StringGrid.AsmJob:= AsmJob;


**Free:**

Form -> StringGrid -> AsmJob -> Sam1,Sam2

我真的不明白在它被释放后我试图双重释放或覆盖对象的位置.

编辑:

我得到的一些错误:

> FastMM在a期间检测到错误
自由块扫描操作. FastMM
检测到一个块已经存在
被释放后修改.
> FastMM在a期间检测到错误
自由块扫描操作.块
标头已损坏.

详情:

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.

编辑:

感谢大家.不,我感觉我正朝着好的方向前进.

程序的结构更复杂我只提供了保持原始帖子小的骨干.但到底是什么,它已经变大了:)
因此,那些TSam对象用于从磁盘加载数据.每个对象中有一个文件.他们还在进行一些处理和数据验证.对于这些TSam中的每一个,我还有一个图形对象,在屏幕上(图形地)显示TSam对象中包含的数据. TStringGrid中的每一行也以TSam显示数据,但是以文本方式显示.

我有一个问题:如果我以较小的碎片打破程序以找出错误的位置,错误仍会出现?或者只能在此特定配置中出现?

回答“如何将AsmJob分配给TStringGrid,以便TStringGrid破坏AsmJob,你能告诉我们吗?”

MyGrid = TStringGrid
  public 
    AsmJob: TAsmJob; 
  end;

然后在TForm.Create(保存网格的形式)的某个地方,我这样做

MyGrid.AsmJob=AsmJob;

在我的MyGrid的析构函数中:

begin 
  FreeAndNil(AsmJob); 
  inherited 
end;

解决方法

此错误意味着您的代码损坏了内部内存管理器的结构.当MM检测到这个时,你的调用堆栈代表点.这不是错误路径或与之相关的任何内容.实际错误发生在此刻之前.
它可能与提到的类有关,也可能没有关系.

You should try to use “Range check errors” option (don’t forget to make Build,not Compile) and FastMM in full debug mode (with CheckHeapForCorruption,CatchUseOfFreedInterfaces и DetectMMOperationsAfterUninstall options enabled).

您还可以打开FullDebugModeScanMemoryPoolBeforeEveryOperation全局变量,在问题发生后几乎立即得到错误,但是此选项会减慢执行速度A LOT.

可能最好的选择是定期调用ScanMemoryPoolForCorruptions.在一个地方叫它.出了错误?马上打电话吧.仍有错误?再打电话吧.没错误?你的问题介于最后一次通话之间.现在,您可以使用FullDebugModeScanMemoryPoolBeforeEveryOperation变量来获取精确位置.只需在此代码区域打开它,然后立即将其关闭.

有一个非常类似的错误:“FastMM在被释放后检测到块已被修改”.在这种情况下,您的代码不会修改内部结构,而是修改根本不使用的其他内存(“可用内存”).

顺便说一下,你的错误不是双重的!如果这是一个双重免费调用,FastMM会明确告诉你(很容易检测到,因为你试图释放未使用或不存在的内存块):“已尝试释放/重新分配未分配的块“.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读