[英]Is there anyway to check if there is memory leaks in C?
我最近了解了memalloc()和free(),我只是想知道是否有一种方法可以适当地检查是否所有的memallocs是否都被适当地释放了?
我在这里有这段代码用于实现双链表,并且不清楚id是否需要遍历每个节点并释放每个p1和p2,还是只算一次?
struct s {
int data;
struct s *p1;
struct s *p2;
};
void freedl(struct s *p)
{
if(p->p1 != NULL)
{
printf("free %d \n", p->p1->data);
}
if(p->p2 != NULL)
{
freedl(p->p2);
}
else
{
printf("free last %d", p->data);
free(p);
}
}
int main(void) {
struct s *one, *two, *three, *four, *five, *six;
one = malloc(sizeof *one);
two = malloc(sizeof *two);
three = malloc(sizeof *three);
four = malloc(sizeof *four);
five = malloc(sizeof *five);
six = malloc(sizeof *six);
one->data = 1;
one->p1 = NULL;
one->p2 = two;
two->data = 2;
two->p1 = one;
two->p2 = three;
three->data = 3;
three->p1 = two;
three->p2 = four;
four->data = 4;
four->p1 = three;
four->p2 = five;
five->data = 5;
five->p1 = four;
five->p2 = six;
six->data = 6;
six->p1 = five;
six->p2 = NULL;
freedl(one);
return EXIT_SUCCESS;
}
我只想确保我做得对!
答案是“是”。 到底有多难,取决于您所使用的操作系统。
(可能还有Hai句)
您可以使用一个名为valgrind
的实用程序。 这是一个出色的实用程序,其目的是(尤其是)检查内存泄漏。
基本用法很简单:
valgrind ./my-program
虽然它是一个复杂的实用程序,所以我建议您查阅valgrind手册以了解更多高级用法。
实际上,它的作用远不止于此,因为它可以检测到许多(但不是全部)越界访问和类似问题。 它还包括其他可能有用的工具,例如用于分析代码的callgrind
。
但是请注意,由于运行方式, valgrind
将使程序运行非常缓慢。
不幸的是,没有适用于Windows的实用程序(无论如何,没有免费的实用程序;而商用的实用程序却花了一笔不小的钱,最后我检查过---并没有valgrind
和朋友能做的那么多)。
但是,您可以执行宏并在退出时手动检查:
#define malloc(size) chk_malloc(size, __FILE__, __LINE__)
#define free(ptr) chk_free(ptr, __FILE__, __LINE__)
// etc... for realloc, calloc
...
// at start of main():
atexit(chk_report); // report problems when program exits normally
然后,您必须实现chk_malloc
, chk_free
等。 但是,如果您执行诸如setAllocator(malloc)
类的操作,可能会有一些“泄漏”。 如果您可以接受丢失线路信息的信息,则可以尝试执行以下操作:
#define malloc chk_malloc // chk_malloc now only takes 1 argument
#define free chk_free
...
有一些黑客这将让你保持文件/行信息即使有这样#define
,但他们的问题严重复杂化(这将涉及基本封黑客进入C)。
如果您不希望以任何方式更改代码,则可以尝试替换那些函数(通过用自己的填充DLL替换stdlib)来试试运气,尽管您不会以这种方式获取文件/行信息。 如果编译是静态完成的,或者编译器已将其替换为某些内在函数(对于malloc
来说不太可能,但并非不可想象),这也可能会带来问题。
实现可以很简单,也可以很复杂,具体取决于您。 我不知道任何现有的实现,但是您可能可以在网上找到一些东西。
系统分配器可以通过某种方式获取统计信息(例如分配的字节)。 (在Linux上为mallinfo )。 在程序的开始,您应该存储分配的字节数,最后不需要确保数目相同。 如果数字不同,则可能存在内存泄漏。
发现泄漏是另一回事。 valgrind之类的工具会有所帮助。
您可以使用valgrind
但速度可能会有些慢,或者在编译器中有内置功能。 例如在clang
(我也认为在gcc 4.9中)有LeakSanitizer
:
$ cat example.c
int main()
{
malloc(100);
return 0;
}
$ clang -fsanitize=leak -g example.c -fsanitize=address
$ ASAN_OPTIONS=detect_leaks=1 ./a.out
=================================================================
==9038==ERROR: LeakSanitizer: detected memory leaks
Direct leak of 100 byte(s) in 1 object(s) allocated from:
#0 0x46c871 (/home/debian/a.out+0x46c871)
#1 0x49888c (/home/debian/a.out+0x49888c)
#2 0x7fea542e4ec4 (/lib/x86_64-linux-gnu/libc.so.6+0x21ec4)
SUMMARY: AddressSanitizer: 100 byte(s) leaked in 1 allocation(s).
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.