【问题标题】:Possible obscure causes for Abstract Error in Delphi?Delphi中抽象错误的可能原因?
【发布时间】:2012-08-12 18:05:57
【问题描述】:

在一个 Delphi 7 项目中,我们安装了 FastMM。不久之后,我们注意到其中一个表单在关闭时开始发出抽象错误消息。我已经对此进行了广泛的调试,但到目前为止我找不到原因。此错误消息的通常原因似乎不适用于此处。该应用程序没有定义抽象类。我还在表单中搜索了可能使用 TStrings 或类似的东西。最重要的是,我们没有(好吧,我们认为我们没有)对此表单进行任何更改。它刚刚坏了。

  1. 除了尝试调用未实现的方法之外,还有其他可能导致此错误的原因吗?
  2. FastMM 是否有可能在应用程序中启用了一些隐藏到现在仍然隐藏的错误?

如果这些问题的答案是否定的,那么我将继续搜索未实现的方法调用,并为我没有遗漏其他东西而松了一口气。

【问题讨论】:

  • 我在创建表单时遇到“抽象错误”,通常发生在您创建表单(Form1),添加组件等然后创建另一个继承Form1的表单(Form2)时,保存一切,到目前为止一切都很好,现在,如果您修改 Form1(添加组件,修改组件属性...)保存并重建,当创建 form2 -> bam,抽象错误,从那时起,我一直避免表单继承在设计中。

标签: delphi fastmm


【解决方案1】:

如果存在内存损坏,则可能会引发各种错误,并且很难找到原因。

回答您的问题:1) 是的,抽象错误也可能是由内存损坏引起的,并且 2) 是的,启用 FastMM 可以使通常被忽视的错误可见(但仍应修复)。

查找内存错误的一些一般建议:

  1. 尝试在 FastMM 中设置“FullDebugMode”。
  2. 确保您创建的所有内容都与免费匹配。
  3. 确保没有任何东西被释放超过一次。
  4. 确保对象在被释放后(或在创建之前)未被使用。
  5. 打开提示和警告(并在出现时修复它们)。

【讨论】:

  • +1。我会添加5. Turn on hints and warnings (and fix them when they occur)
  • @KenWhite:当然。我会这样做1. Turn on hints and warnings...,强调1. :-)
  • @KenWhite 已添加 :-) 唯一的问题是,在遗留代码中可能存在数百个警告,并且(错误地)修复它们有引入新错误的风险。所以一定要慎重。
  • 与数字 2 相关。这将“仅”导致内存泄漏,而不是访问冲突。
  • 为了解决 EscapeVelocity 的问题,我将专注于 4.
【解决方案2】:

“它刚刚坏了”——它可能总是坏了,但现在你知道了。

我在关闭表单作为按钮事件的一部分时遇到了问题。表单被销毁,然后按钮消息的其余部分被分派到不再存在的按钮。 Release 方法通过(从内存中)将 wm_close 消息发送回表单来避免这种情况

【讨论】:

  • 您的回答对我有帮助。我有一个按钮会自行删除并添加新按钮。诀窍是在按钮代码退出后设置信号量以重新加载。
【解决方案3】:

回答问题 1“除了尝试调用未实现的方法之外,还有其他可能导致此错误的原因吗?”

是的。这就是在我的情况下导致抽象错误的原因:

TWinControl(Sender).Visible:= FALSE;        

这在发件人是 TButton 时有效,但在发件人是其他东西(如 TAction)时引发错误(当然)。这显然是我的错。我应该使用“as”而不是硬类型转换。

问题 2 的答案:是的。我也看到了这种情况。我们应该很清楚,这并不意味着 FastMM 有问题。该错误是“休眠的”。 FastMM 只触发了它。
实际上,您应该更多地依靠 FastMM 来找到您的问题。为此,将 FastMM 切换到完全调试模式。它将帮助您:

确保对象在被释放之后(或之前)未被使用 已创建)

另外,在某些情况下,整个项目都搞砸了,我得到了 Abstract 错误。在我删除 DPROJ 文件之前没有任何效果。只需将您当前的 DPROJ 文件与您背后的文件进行比较,您就会看到 IDE 是如何整理文件的。

您还必须修复编译器显示的所有警告!编译器对此很认真。如果没有正当理由,它不会发出警告。解决它,您可能会解决您的问题。

在这种特殊情况下,我还将所有 .Free 替换为 FreeAndNil()

【讨论】:

    【解决方案4】:

    您可以尝试将 u_dzAbstractHandler 添加到您的项目中。它应该在调用该方法的地方引发抽象错误,因此更容易调试它。当然这只有在调试器中运行时出现错误时才有帮助。

    https://osdn.net/projects/dzlib-tools/scm/svn/blobs/head/dzlib/trunk/src/u_dzAbstractHandler.pas

    【讨论】:

    • 如何安装?你只是把单元放到项目的USES列表中?
    • 是的,就这么简单。
    【解决方案5】:

    可能是您的基类中的一个抽象函数/过程没有实现;

    试试这个:

    例如

     type
    
       TBaseClass = class (TObject)
    
     public
    
          procedure DoSomething;  virtual; abstract; //not implemented procedure
    
     end;
    
    
      type
    
        TInheritedClass = class (TBaseClass)
    
     public
    
          procedure DoSomething; override;
    
       end;
    
    //Implementation
    
    procedure TInheritedClass.DoSomething;
    
    begin
    
     //your code
    
    end;
    

    【讨论】:

      猜你喜欢
      • 2011-05-22
      • 1970-01-01
      • 2017-06-25
      • 2012-07-24
      • 1970-01-01
      • 2012-10-10
      • 2013-06-25
      • 1970-01-01
      • 2011-11-18
      相关资源
      最近更新 更多