我遇到了这个讨厌的错误,该错误过去已经消失了,但是现在已经过了一段时间。

我创建了两个TSam对象(从TPersistent派生)并将其加载到TAsmJob对象(从TObjectList派生)。

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

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

该程序的主干如下所示:

**Create:**

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


**Free:**

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

我真的不明白在释放对象之后我该在哪里尝试双重释放或覆盖该对象。

编辑:

我遇到的一些错误:
  • FastMM在运行过程中检测到错误
    自由块扫描操作。快速MM
    检测到一个块已经被
    释放后进行修改。
  • FastMM在运行过程中检测到错误
    自由块扫描操作。块
    header 已损坏。

  • 细节:
    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设置为 super 主动 Debug模式。没有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将明确告诉您(很容易检测到,因为您正在尝试释放未使用或不存在的内存块):“已尝试释放/重新分配内存。未分配的块”。

    10-05 22:40