32

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

注意:我想在没有任何外部实用程序的情况下进行练习。

4

5 回答 5

51

正如建议的那样,已经存在像 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,其中您检查要求根据您的链接列表释放的地址条目。如果没有匹配的条目,则表示使用错误,您可以标记它。

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

请注意,在使用此宏技巧时,您会丢失函数提供的类型检查,但这是我经常使用的一个巧妙的小技巧。

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

于 2012-01-31T04:13:08.353 回答
15

Valgrind是您所需要的。

我记得读过简述算法的第一章,虽然没有包含代码,但它谈到了这一点。只是添加,以防您觉得有趣。

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

事实上,你可以。读取 LD_PRELOAD。

于 2012-01-31T04:08:46.203 回答
6

除了@Als's answer将在您的源代码中包装调用之外,如果您使用的是 gnu ld,则可以让链接器在链接时包装所有调用(大概是mallocrealloccallocfree),而不管它们来自哪里。然后,您编写__wrap_mallocetc 并可以使用例如__real_malloc.

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

我不知道这如何与来自共享库的调用一起工作。我猜它不会。

于 2012-01-31T04:26:57.650 回答
4

使用 mallinfo 函数,它使用 Xilinx SDK gcc 在 Xilinx Zynq 裸机上为我工作。我测试了故意的内存泄漏——我不知道为什么,但是谷歌的结果在发现这个解决方案传播信息以帮助其他开发人员时非常糟糕!

于 2017-05-03T06:18:04.957 回答
2

以下是如何修改 malloc、免费钩子:Malloc 的钩子

于 2015-07-15T20:35:23.787 回答