7

以前、C (ビジュアル スタジオ) の動的メモリで問題が発生しました。バッファの 1 つを解放するときに実行時エラーをスローする、多かれ少なかれ機能するプログラムがありました。これは明らかなメモリ破損であり、プログラムはバッファの末尾を上書きしました。

私の問題は、追跡に非常に時間がかかることです。破損後にエラーがスローされたため、実行全体を手動でデバッグして、バッファの終わりがいつ上書きされたかを確認する必要がありました。

この問題の追跡を支援するツールはありますか? プログラムがすぐにクラッシュしていたら、もっと早く問題を発見できたでしょう...

問題の例:

int *pNum = malloc(10 * sizeof(int));

//                 ||
//                 \/    
for(int i = 0; i < 13; i++)
{
pNum[i] = 3;
}

// error....
free(pNum);
4

4 に答える 4

4

そのために「データブレークポイント」を使用します。あなたの場合、プログラムがクラッシュすると、最初に次のように文句を言うかもしれません:

00397848 のヒープ ブロックが 0039789C で変更され、要求されたサイズが 4c を超えました

次に、プログラムを再度開始し、 address にデータ ブレークポイントを設定します0039789C。コードがそのアドレスに書き込むと、実行が停止します。この時点ですぐにバグを見つけることがよくあります。

プログラムがメモリの割り当てと割り当て解除を繰り返し、それがたまたまこの正確なアドレスにある場合は、単に割り当て解除を無効にします。

_CrtSetDbgFlag(_CrtSetDbgFlag(_CRTDBG_REPORT_FLAG) | _CRTDBG_DELAY_FREE_MEM_DF);
于 2012-06-10T18:14:55.473 に答える
3

私はpageheapを使用します。これは、アロケータの動作を変更する Microsoft のツールです。ページヒープがオンの場合、malloc を呼び出すと、割り当ては最も近いページ (メモリのブロック) に切り上げられ、読み取り/書き込み禁止に設定された仮想メモリの追加ページがその後に配置されます。割り当てる動的メモリは、バッファの末尾が仮想ページの前のページの末尾の直前になるように調整されます。このようにして、多くの場合 1 バイトでバッファーの端を超えた場合、デバッガーはそれを簡単にキャッチできます。

于 2012-06-11T04:59:31.200 に答える
2

この問題の追跡を支援するツール\方法はありますか?

はい、それはまさに静的コードアナライザーが見つけようとするタイプのエラーです。例splint/PC-Lint

このようなツールのリストは次のとおりです。http: //en.wikipedia.org/wiki/List_of_tools_for_static_code_analysis

編集:コードスニペットでスプリントを試してみると、次の警告が表示されます。

main.c:9:2:範囲外の可能性のあるストア:pnum [i]

おそらく、この警告はあなたを助けたでしょう。

于 2012-06-10T12:18:33.457 に答える
0

当社のCheckPointerツールは、メモリ管理エラーを見つけるのに役立ちます。GCC 3/4 および C の Microsoft 方言で動作します。

多くの動的チェッカーは、オブジェクトの外部へのアクセスのみをキャッチし、オブジェクトがヒープに割り当てられている場合にのみキャッチします。CheckPointer は、ヒープ割り当てオブジェクト内のメモリ アクセス エラーを検出します。フィールドの型に関係なく、構造体のフィールドの最後にアクセスすることは違法です。ほとんどの動的チェッカーは、このようなエラーを検出できません。また、ローカルの端から離れたアクセスも検出します。

于 2012-06-26T08:08:49.153 に答える