3

我有一个应用程序将所有动态创建的数据模块加载到 TList 中。应用程序在 windows XP 操作系统下运行。从应用程序关闭按钮关闭应用程序时,代码会正确执行。但是当从任务栏菜单关闭应用程序时,会引发无效指针操作。当以不同的方式关闭应用程序时,相同的代码表现不同。

负责销毁数据模块的代码

  for iPos := 0 to FDatamodules.Count - 1 do //FDataModules is of type TList
    if FDatamodules.Items[iPos] <> nil then 
      TDatamodule(FDatamodules.Items[iPos]).Free;

和堆栈

:7c812a6b kernel32.RaiseException + 0x52
System.TObject.FreeInstance
System.ErrorAt(2,$4A7FEFC)
System.Error(reInvalidPtr)
System.TObject.FreeInstance
System._ClassDestroy(???)
Classes.TDataModule.Destroy
System.TObject.Free
RBAFORM.TRBABaseForm.Destroy

LE:似乎从任务栏菜单关闭应用程序正在向应用程序发送 HALT(0) 并且数据模块被释放。在下图中:左边是正常关闭操作的堆栈,右边是从任务栏菜单关闭应用程序的堆栈。

在此处输入图像描述

4

1 回答 1

8

这似乎是一个双重释放问题(就像 LU 对您的问题发表的评论),这意味着您不止一次释放数据模块的实例。

当您创建Create(nil)不属于任何人的实例时,您可以安全地调用Free它。(另见组件构造函数中 nil owner 的含义是什么

如果您使用Create(Form1)(非 nil 参数)创建它,那么您不再有责任调用Free. Form1在本例中释放时会自动释放。

要确定发生了什么,您应该在 FullDebugMode 或类似的内存调试器中使用 FastMM。内存调试器应该能够发现问题并为您提供更多有用的信息。

于 2013-02-17T11:15:55.863 回答