3

動的に作成されたすべてのデータ モジュールを TList にロードするアプリケーションがあります。アプリケーションは Windows XP OS で実行されています。アプリケーションの閉じるボタンからアプリケーションを閉じると、コードが正しく実行されます。ただし、タスクバー メニューからアプリケーションを閉じると、無効なポインター操作が発生します。さまざまな方法でアプリケーションを閉じると、同じコードでも動作が異なります。

データモジュールの破棄を担当するコード

  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所有者の意味も参照してください)

(nil 以外の引数) を指定して作成すると、Create(Form1)を呼び出す責任はなくなりますFreeForm1この例で が解放されると、自動的に解放されます。

何が起こっているのかを確認するには、FastMM を FullDebugMode で使用するか、同様のメモリ デバッガーを使用する必要があります。メモリ デバッガーは、問題をキャッチし、より役立つ情報を提供できるはずです。

于 2013-02-17T11:15:55.863 に答える