8

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

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

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

4

5 回答 5

12

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

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

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

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

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

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

于 2012-08-13T03:27:56.303 回答
2

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

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

于 2012-08-13T08:42:25.593 回答
2

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

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

TWinControl(Sender).Visible:= FALSE;        

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

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

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

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

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

在这种特殊情况下,我还将全部替换.FreeFreeAndNil().

于 2014-08-29T09:59:59.923 回答
0

可能是您的基类中的抽象函数/过程之一未实现;

试试这个 :

例如

 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;
于 2018-10-09T11:49:16.767 回答