检测C程序中的内存泄漏?

Mik*_*e G 25 c memory-leak-detector

如果我们想检查C++程序中的内存泄漏,我们可以重载newdelete运算符来跟踪分配的内存.如果我们想检查C程序中的泄漏怎么办?由于C中没有运算符重载,我们是否可以覆盖malloc函数指针来拦截调用malloc和跟踪内存分配?没有使用任何外部工具有没有更简单的方法?请提供一些代码,因为我不熟悉覆盖方法指针.

注意:我想在没有任何外部实用程序的情况下执行此操作.

Alo*_*ave 44

正如所建议的,已经存在像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;
}
Run Code Online (Sandbox Code Playgroud)

您维护一个链接的地址列表,其中包含分配的文件和行号.您使用您的条目更新链接列表malloc.

与上面类似,您可以编写一个实现free,其中您检查要求释放链接列表的地址条目.如果没有匹配的条目,则表示使用错误,您可以将其标记出来.

在程序结束时,您可以将链接列表的内容打印或写入日志文件.如果没有泄漏,您的链表应该没有条目,但如果有一些泄漏,那么日志文件会为您提供内存分配位置的确切位置.

请注意,在使用这个宏技巧时,你会丢失哪些函数提供的类型检查,但这是我使用很多次的一个巧妙的小技巧.

希望这会有所帮助,并且一切顺利:)

  • @AlokSave你不觉得会有无限的递归吗?因为我们在my_malloc中调用malloc,它将被预处理到my_malloc.所以它应该有效地导致堆栈溢出! (5认同)
  • 你可以,但这不会给你你想要的粒度.所以你丢失了2000个字节.它是一个2000字节的分配还是10个200字节的分配?列表可以为您节省大量时间来完成日志,以便进行匹配. (3认同)

Abh*_*ogi 13

Valgrind是你需要的.

我记得读过Nutshell中算法的第一章,虽然它没有包含代码,但它还是讨论了这个问题.只是添加,以防你觉得它很有趣.

由于c中没有运算符重载,我们可以覆盖malloc函数点来拦截对malloc的调用并跟踪内存分配

实际上,你可以.读取LD_PRELOAD.

  • @KerrekSB:玩弄它没有错,这肯定是一次很棒的学习经历.当然,在实时项目环境中,valgrind是最好的,但我必须承认,当我长时间做这件事时,这对我来说是一个很好的学习前. (5认同)

smp*_*kes 5

除了@阿尔斯的答案,将在源代码包调用,如果你使用GNU ld,你可以有链接包装所有电话(大概是为了mallocrealloccalloc,和free)在链接时,不管他们来自哪里。然后,您编写__wrap_mallocetc并可以使用调用原始函数__real_malloc

--wrap=symbolhttp://ftp.gnu.org/old-gnu/Manuals/ld-2.9.1/html_node/ld_3.html

我不知道如何使用共享库中的调用。我猜不是。