32

C++ プログラムでメモリ リークをチェックしたい場合は、newanddelete演算子をオーバーロードして、割り当てられたメモリを追跡できます。C プログラムのリークをチェックしたい場合はどうすればよいでしょうか? C には演算子のオーバーロードがないため、関数ポインターを上書きしてmalloc呼び出しをインターセプトしmalloc、メモリ割り当てを追跡できますか? 外部ユーティリティを使用せずに簡単な方法はありますか? メソッドポインターの上書きに慣れていないので、コードを提供してください。

注:練習用の外部ユーティリティなしでこれを行いたいと思います。

4

5 に答える 5

51

示唆されているように、これを行うための Valgrind などの優れたツールが既に存在します。

さらに遠く:

練習用の外部ユーティリティなしでこれを行い
たい
. プロジェクトに単一の割り当ておよび割り当て解除機能がある限り、これを行うことができるはずです。

#define malloc(X) my_malloc( X, __FILE__, __LINE__, __FUNCTION__)

void* my_malloc(size_t size, const char *file, int line, const char *func)
{

    void *p = malloc(size);
    printf ("Allocated = %s, %i, %s, %p[%li]\n", file, line, func, p, size);

    /*Link List functionality goes in here*/

    return p;
}

ファイルとそこから割り当てられた行番号で割り当てられているアドレスのリンクされたリストを維持します。のエントリでリンク リストを更新しますmalloc

上記と同様に、 の実装を記述できます。この実装ではfree、リンクされたリストに対して解放するよう求められているアドレス エントリをチェックします。一致するエントリがない場合は、使用法エラーであり、フラグを立てることができます。

プログラムの最後に、リンク リストの内容をログ ファイルに出力または書き込みます。リークがない場合、リンクされたリストにはエントリがありませんが、リークがある場合は、ログファイルにメモリが割り当てられた正確な場所が示されます。

このマクロ トリックを使用すると、関数が提供する型チェックが失われることに注意してください。

これが役に立てば幸いです:)

于 2012-01-31T04:13:08.353 に答える
15

Valgrindが必要です。

コードは含まれていませんが、これについて話しているアルゴリズムの要約の最初の章を読んだことを覚えています。面白いと思った場合にのみ追加します。

cには演算子のオーバーロードがないため、malloc関数ポイントを上書きして、mallocの呼び出しをインターセプトし、メモリ割り当てを追跡できますか

実際、できます。LD_PRELOAD を読み取ります。

于 2012-01-31T04:08:46.203 に答える
6

ソース コードで呼び出しをラップする @Als の回答に加えて、 gnu を使用している場合は、リンク時にldすべての呼び出し (おそらくmallocrealloccalloc、および) をリンカーにラップさせることができます。free次に etc を記述__wrap_mallocし、元の関数を呼び出すことができます__real_malloc

http://ftp.gnu.org/old-gnu/Manuals/ld-2.9.1/html_node/ld_3.htmlを参照--wrap=symbolしてください。

これが共有ライブラリからの呼び出しでどのように機能するかわかりません。そうではないと思います。

于 2012-01-31T04:26:57.650 に答える