web-dev-qa-db-ja.com

Cプログラムでメモリリークを検出しますか?

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

注:練習用の外部ユーティリティを使用せずにこれを実行したいと思います。

24
Mike G

提案されているように、これを行うための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の実装を記述できます。ここでは、リンクリストに対して解放するよう要求されているアドレスエントリをチェックします。一致するエントリが存在しない場合は使用エラーであり、フラグを立てることができます。

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

このマクロトリックを使用すると、関数が提供する型チェックを失うことに注意してください。しかし、それは私が何度も使用するきちんとした小さなトリックです。

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

45
Alok Save

Valgrind が必要です。

Nutshellのアルゴリズム の最初の章を読んだことを覚えています。おもしろいと思う場合に追加しました。

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

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

13

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

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

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

5
smparkes

ザイリンクスSDK gccを使用して、ザイリンクスZynqベアメタルで機能したmallinfo関数を使用します。私は意図的なメモリリークでテストしました-なぜこのソリューションが他の開発者を助けるためにWordを広めたのか、Googleの結果は信じられないほどひどいものでした!

2
Mister Pidot

以下に、malloc、フリーフックを変更する方法を示します。 Mallocのフック

1
TJP