3

我想在调用函数之前和之后获取分配的总内存,以确定我是否正确释放了所有内容。

我在 C 中做这个,我很生疏,如果这是一个幼稚的问题,请原谅我。我正在寻找类似于 C# GC.GetTotalMemory(true) 的东西,目前在 Windows 中。

现在我在调用函数之前和之后使用PROCESS_MEMORY_COUNTERS_EXand GetProcessMemoryInfo(...),但我无法对输出做出正面或反面,因为如果我进入函数并注释掉一个调用,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 分配的当前总内存大小?

4

3 回答 3

5

我不知道任何可以帮助您实现这一目标的 c 标准库函数。AFAIK,不存在任何。但是您可以使用某种 hack,不应在发布版本中使用它,而仅用于调试和诊断目的。

您可以在 c 中使用我所说的 malloc 重载。你可以在宏的帮助下做到这一点。
您可以在 上编写一个包装函数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

几年前(在 Stack Overflow 的这些美好日子之前!)我做了类似的事情,使用我自己的mallocand函数在调用 real和函数free之前和之后记录了一些指标。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

如果您需要大量运行时指标,有更好、更全面的第三方库等可以提供更多信息;但是,当您需要在紧要关头检查某些东西时,这是一个快速的小技巧。

于 2012-05-06T18:31:51.913 回答
0

您可以使用Valgrind检查是否在进程退出时释放了所有动态分配的内存。

于 2012-05-06T18:23:29.653 回答