2012-05-06 21 views
3

すべてを正しく解放したかどうかを判断するために、関数を呼び出す前後に割り振られた合計メモリーを取得したいとします。CでのGetTotalMemory割り振り

私はこれをCでやっています。私は非常に錆びていますので、これが素朴な質問であれば私を許してください。私はC#GC.GetTotalMemory(真)と似たようなものを探していますが、これはWindows版です。

今、私は前にして関数を呼び出した後、PROCESS_MEMORY_COUNTERS_EXGetProcessMemoryInfo(...)を使用していますが、私は、関数に入るとfree(...)への呼び出しをコメントアウトした場合、それは私を与えるので、私は、出力の頭や尾をすることはできません同じ結果(後は常に大きい)。ここでは、このような結果に

GetProcessMemoryInfo(hProc, &before, sizeof(before)); 
r = c->function(); 
GetProcessMemoryInfo(hProc, &after, sizeof(after)); 

if(r->result != 0) { 
    printf("error: %s\r\n", c->name); 
    printf(" %s\r\n", r->message); 
    printf(" %s (%d)\r\n", r->file, r->line); 
    failed++; 
} 
else if(after.PrivateUsage > before.PrivateUsage) { 
    printf("memory leak: %s\r\n", c->name); 
    printf(" %d kb\r\n", after.PrivateUsage - before.PrivateUsage); 
    failed++; 
} 
else succeeded++; 

...私が今持っているものです。

after.PrivateUsage - before.PrivateUsage = 12288 

私が行くと私は同じ結果を得る解放するためにいくつかの呼び出しをコメントアウトした場合。 mallocを使用して割り当てたメモリの現在の合計サイズを実際にどのように決定できますか?

+0

あなたはメモリリークを検出したり、パフォーマンス指標のいくつかの並べ替えのためのメモリ使用を追跡しようとしていますか? –

+0

メモリリークが、今あなたがそれを述べるので...私は実際にちょうど私のコードのテストを書いていると私はすべてを解放していることを確認します。私はコードが気密であることを確認したい。 –

+0

私はそれを使用していないが、私は、Visual Studioは、あなたが望むことのように聞こえるCRTデバッグヒープと呼ばれる機能を持っていますことをお読みください。http://msdn.microsoft.com/en-us/library/974tc9t1(v= vs.85).aspx独自のバージョンを作成するよりも既存の機能を使用するほうが堅牢になる可能性があります。しかし、私はWindowsでプログラムしていないので、これがあなたが望むものであれば確かに言えるでしょう。 –

答えて

5

私は、これを達成するのに役立つ標準的なライブラリ関数は認識していません。 AFAIK、存在しない。しかし、あなたは何らかの種類のハックを使うことができます。リリースビルドでは使用しないでください。デバッグと診断の目的にのみ使用してください。

mallocオーバーロードをcで使用できます。あなたはマクロの助けを借りてこれを行います。あなたには、いくつかの中に診断を収集することができ、独自の関数内

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; 
} 

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


あなたは機能はシンプルなマクロが十分でなければならその後、呼び出されたコード内でそれぞれ、すべてのインスタンスを変更することなく、malloc上でラッパー関数を書くことができますグローバルなデータ構造、例えばリンクされたリスト 例:これは、返されるバッファアドレス、対応する割り当てのサイズなどを含むことができます。
同様に、free()をオーバーロードして、そこで簿記を行うことができます。関数に渡される各バッファアドレスは、アイテムがリストされ、一致するものが見つかったときにリストから削除されます。
リストの最後には、割り振られたことはありますが解放されたことのないメモリのエントリ、つまりメモリリークが含まれています。必要に応じて更新されたリストから診断の詳細を取得するためにいくつかのAPIを提供することができます。

デバッグの目的で、このトリックを使用して独自のメモリリーク検出器などを書き込むことができます。

+3

あなたの'の#defineを言ったと思います。 –

+0

私は実際にこれをやって検討していた誰かが、私はおそらく、実際にこれを行います –

+0

@trinithisより良いアイデアを思い付くことができなければ私は私が何かを明らかに:(欠けしなければならないと思った:。!のErm、はい確かに –

0

Valgrindを使用すると、プロセス終了時にすべての動的に割り当てられたメモリを解放したかどうかを確認できます。

+0

は、私は質問には、Windows .... my_malloc' 'の定義の後に来る必要がmalloc' –

3

私は(スタックオーバーフローのこれらの偉大な日の前に!)この年前のような何かをした前に、実際のmallocfree関数を呼び出した後、いくつかの指標を記録し、私自身mallocfree機能を使用することによって。

あなたは、プラットフォームに依存しない、このような何かを、行うことができます:

// in some common header file, let's say mem_metrics.h 
#define malloc malloc_with_metrics 
#define free free_with_metrics 

extern size_t num_current_allocs; 
void* malloc_with_metrics(size_t size); 
void free_with_metrics(void* ptr); 


// in mem_metrics.c 
#undef malloc 
#undef free 

size_t num_current_allocs = 0; 

void* malloc_with_metrics(size_t size) 
{ 
    ++num_current_allocs; 
    return malloc(size); 
} 

void free_with_metrics(void* ptr) 
{ 
    --num_current_allocs; 
    free(ptr); 
} 

num_current_allocsにアクセスすることにより、任意の時点で存在しているどのように多くの割り当て、レコード、上記の例。このアイデアは、有用な指標を記録することで拡張することができます。プログラムを終了するときによくnum_current_allocsが0であることを確認するためによく使用します。

もう一つの例:私は一度、バイト単位でのポインタのテーブルとそれに対応するサイズを維持malloc_with_metricsが呼び出されたときに、新しいポインタとそのサイズを追加し、free_with_metricsが呼び出されたときにそれらを除去することにより、いくつかの未解放されたバイトを見つけるために、このようなものを使用。より多くの情報を与える

あなたは、ランタイム・メトリックの多くを必要とする場合は、より良い、より徹底したサードパーティ製のライブラリがなどがあります。しかし、ピンチで何かをチェックする必要があるときは、これはすばやく簡単です。

+0

あなたの両方が良い答えを持っていたが、悲しいかな、1つしかないかもしれません。 –

関連する問題