12

私はこれを理解できないようです。プログラムは正常にコンパイルおよび実行されますが、デバッグ中にのみ、プログラムをシャットダウンするときに「無効なポインター操作」というメッセージ ボックスが表示されます。すべての FormCloseQuery および FormDestory イベントを念入りにチェックして、構文または論理エラーがないか確認しました。何も見つかりませんでした。エラーなしで期待どおりに実行されます。

ここに画像の説明を入力

無効なポインタ操作エラーで中断するようにコンパイラに指示すると、コンパイラは何もせず、プログラムをハングアップさせます。その時点で、プロセスを終了または強制終了する必要がありました。

どうやってこれを理解しますか?

前もって感謝します、

4

4 に答える 4

33

無効なメモリを解放しようとすると、メモリマネージャによって無効なポインタ例外がスローされます。これが発生する可能性のある3つの方法があります。

最も一般的なのは、すでに解放したオブジェクトを解放しようとしているためです。FastMMのFullDebugModeをオンにすると、これが検出され、問題が直接示されます。(ただし、有用なスタックトレースを作成するために必要な情報が含まれるように、必ずマップファイルを作成してください。)

2番目の方法は、メモリマネージャ以外の場所に割り当てられたメモリを解放しようとしている場合です。DelphiEXEから共有メモリマネージャ機能を使用していないDelphiDLLに文字列を渡すときに、これを数回見ました。

そして3番目の方法は、ポインタを直接いじることを含み、おそらくあなたには当てはまりません。FastMMによって割り当てられた実際のメモリブロックを参照しないポインタを使用しようとするとFreeMem、このエラーが発生します。Dispose

それはおそらく最初のものです。FullDebugModeを使用すると、問題の原因を簡単に見つけることができます。

于 2012-04-11T20:30:43.610 に答える
11

Delphi メモリ マネージャに属していないメモリを解放するように指示すると、無効なポインタ操作が発生します。次の 3 つの方法が考えられます。

  • 既に解放されているポインターまたはオブジェクトを解放する。
  • 他のメモリ マネージャ (やFreeMemなど) によって割り当てられたものを解放するために使用します。GlobalAllocCoTaskMemAlloc
  • 初期化されていないポインターを解放します。(これは、完全に安全なヌル ポインターの解放とは異なります。)

プログラムのどこかで、これらのことの 1 つを行っています。デバッガーは、メモリ マネージャーによってスローされた例外を検出したので、デバッグを行ってください。スタック トレースから、解放しようとしている変数を確認できるはずです。変数が使用されている他の方法については、プログラムの残りの部分を確認してください。

MadExcept や Eureka Log などのツールは、ダブルフリー エラーを見つけるのに役立ちます。問題のポインターがどこに割り当てられ、どこで最初に解放されたかを追跡できます。これは、間違いを見つけて何度も解放するのをやめるのに十分な情報である場合があります。

于 2013-01-18T15:33:55.107 に答える
2

4 つ目の理由は、無効なポインタ操作が発生する可能性があることです。実数の配列[0..1000]と実数の配列[1..200]である3番目のポインターという2つのポインターがありました。for i := 0 to 1000 で初期化された 3 つのポインターはすべて ptr1^[i]:=0;ptr2^[i]:=0;ptr3^[i]:=0; で始まります。終わり; この貧弱なプログラミングは、Delphi で Pascal を悩ませることはありませんでしたが、3 つのポインターのいずれかを Dispose に呼び出すと、無効なポインター操作が発生しました。修正は、単に 3 番目のポインターを正しく初期化することでした。

于 2016-09-23T21:07:22.787 に答える
0

Delphi のデバッグ中に、このタイプの「表示されたエラー」に遭遇しました。

「関数呼び出しを許可する」が有効になっている監視変数があるかどうか、または初期化されていない可能性のある同じユニット (またはグローバル) 内の他の変数を表示しようとする監視があるかどうかを確認します。ブレークポイントで停止すると、Delphi のデバッガが、初期化されていないポインタまたは変数にアクセスする関数呼び出しを介して値を表示しようとする可能性があります。AVの原因となる実際の変数は、ウォッチリストにさえありません。

于 2013-01-18T14:28:38.820 に答える