2012-01-31 14 views
15

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

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

+4

Valgrindには何が問題なのですか? –

+0

@MitchWheat私は外部のユーティリティを使用することはできません。 –

+0

これは学習のためのものであれば、valgrindがどのようにそれを行うのかを学ぶことができます... –

答えて

35

このように、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の実装を書くことができます。ここでは、リンクされたリストに対して解放するように求められるアドレスエントリを確認します。一致するエントリがない場合、その使用エラーが発生しており、それにフラグを立てることができます。

プログラムの最後に、リンクリストの内容をログファイルに出力します。リークがない場合は、リンクされたリストにエントリがないはずですが、いくつかのリークがあった場合、ログファイルは、メモリが割り当てられた場所の正確な場所を示します。

このマクロトリックを使用すると、どの機能が提供するタイプチェックが失われることに注意してください。しかし、私は多くの時間を使います。

希望はこのことができますし、すべてのベスト、あなたのソースコードで呼び出しをラップしますあなたは、GNU ldを使用している場合、あなたはリンカがすべての呼び出しをラップすることができます@アルスの答えに加えて:)

+0

これは間違いなく興味深いアプローチですが、mallocが呼び出されたときにサイズをいくつかのカウンタに追加して、空きが呼び出されたときにサイズを減算することはできますか? –

+3

あなたはそれがあなたが望むかもしれない粒度を与えるつもりはないかもしれません。あなたは2000バイトを失った。それは2000バイトの割り当てか10 200バイトの割り当てでしたか?リストを使用すると、ログを調べて何かを一致させるために多くの時間を節約できます。 – Duck

+0

@MikeG:そうです、Duckはそう言いましたが、リンクされたリストは柔軟に機能し、障害のある割り当てを正確に判断できます。 –

10

Valgrindが必要です。

私はAlgorithms in a Nutshellの第1章を読んでいましたが、これはコードを含んでいませんでしたが、これについて話しました。あなたが面白いと思っている場合に備えて追加されました。

Cでのオーバーロードなしオペレータがすることができます、我々オーバーライトのmalloc ファンクションポイントは、malloc関数への呼び出しをインターセプトし、実際にメモリ 割り当て

を追跡することができますがないので。 LD_PRELOAD読み取り。

+0

私はValgrindの使い方を知っています。私はそれを自分で実装したいと思っています。 –

+1

@MikeG:これは癌があり、病院について知っていますが、それを自分で練習しようと思っているようです。 –

+5

@KerrekSB:それを使って遊ぶのは間違っていませんが、確かに素晴らしい学習経験です。リアルタイムでは、valgrindが最高ですが、私が長い時間を取ったときには、これは良い学習だと認めなければなりません時間前。 –

4

(おそらくmallocrealloccalloc、およびfree)をリンク時に送信します。 __wrap_mallocなどを書き、元の関数をたとえば__real_mallocと呼ぶことができます。

は、私は、これは共有ライブラリからの電話でどのように動作するか分からない--wrap=symbol

http://ftp.gnu.org/old-gnu/Manuals/ld-2.9.1/html_node/ld_3.htmlで参照してください。私はそれがないと推測しています。ここで

1

は、あなたがmalloc関数を変更することができますどのように無料のフックです:Hooks for Malloc

+1

ハイパーリンクが変わるのを見てください。リンク上に見つかった解決策を説明する必要があります –

1

使用それはザイリンクスSDKのGCCを使用して、ザイリンクスのZynqのbaremetalに私のために働いたmallinfo機能。私は意図的なメモリリークでテストしました - 私は理由がわかりませんが、Googleの結果は、このソリューションが他の開発者を助けるために言葉を広めるのを見つけるのに非常に恐ろしいものでした!