3

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

私は C でこれを行っていますが、非常にさびているので、これが素朴な質問である場合はご容赦ください。C# GC.GetTotalMemory(true) に似たものを探していますが、これは今のところ Windows にあります。

現在、関数を呼び出す前後に and を使用し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

free へのいくつかの呼び出しをコメントアウトすると、同じ結果が得られます。malloc を使用して割り当てたメモリの現在の合計サイズを実際に確認するにはどうすればよいですか?

4

3 に答える 3

5

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

私がmalloc オーバーロードと呼んでいるものを c で使用できます。これは、マクロを使用して行います。関数が呼び出されるコード内のすべてのインスタンスを変更せずに
、ラッパー関数を に書き込むことができます。単純なマクロで十分です。malloc

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__)

独自の関数内で、リンクされたリストなどのグローバル データ構造で診断を収集できます。例:返されるバッファアドレス、その対応する割り当てのサイズなどを維持でき
ます。同様に、オーバーロードfree()し、そこで簿記を行うことができます。関数に渡された各バッファアドレスは、リスト項目に対してチェックされ、削除されます一致が見つかったときにリストから。
プログラムの最後に、リストには、割り当てられたが解放されなかったメモリのエントリが含まれます。これは、メモリ リークとも呼ばれます。必要に応じて、維持されているリストから診断の詳細を取得するための API を提供できます。

多くの場合、このトリックを使用して、デバッグ目的で独自のメモリリーク検出器などを作成できます。

于 2012-05-06T18:24:33.810 に答える
3

私は何年も前に (スタック オーバーフローのこれらの素晴らしい時代の前に!) 、実際のand関数を呼び出す前後にいくつかのメトリックを記録した独自のmallocand関数を使用して、このようなことを行いました。freemallocfree

プラットフォームに依存しない、次のようなことができます。

// 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

多くの実行時メトリクスが必要な場合は、より多くの情報を提供する、より優れた完全なサードパーティ ライブラリなどがあります。ただし、これは、ピンチで何かを確認する必要がある場合の簡単な小さなトリックです。

于 2012-05-06T18:31:51.913 に答える
0

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

于 2012-05-06T18:23:29.653 に答える