我最近了解了memalloc()和free(),我只是想知道是否有办法正确检查是否所有的memalloc都被正确释放了?
我在这里有这个代码用于双链表的实现,并且我不清楚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;
}
我想确保我做得对!
答案 0 :(得分:2)
答案是“是”;究竟有多难取决于你所处的操作系统。
(可能是Haiku)
您可以使用名为valgrind
的实用程序。它是一个优秀的实用程序,专门用于(除其他事项外)确定内存泄漏。
基本用法很简单:
valgrind ./my-program
这是一个复杂的实用程序,所以我建议您查看valgrind manual以获得更高级的用法。
它实际上远不止于此,因为它可以检测到许多(但不是全部)越界访问和类似问题。它还包括可能有用的其他工具,例如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)。
如果您不想以任何方式更改代码,您可以尝试更换这些函数(通过将stdlib替换为您自己的填充DLL),尽管您不会获得文件/行信息办法。如果编译是静态完成的,或者编译器已经用一些内在替换它(malloc
不太可能,但不是不可想象的话),也可能会有问题。
实施可能非常简单,也可能很复杂,取决于您。我不知道任何现有的实现,但您可以可能在线查找内容。
答案 1 :(得分:0)
系统分配器可以通过某种方式获取统计信息(例如分配的字节数)。 (Linux上的mallinfo)。在程序开始时,您应该存储分配的字节数,最后您需要确保数字相同。如果数字不同,则可能存在内存泄漏。
发现泄漏是另一回事。像valgrind这样的工具会有所帮助。
答案 2 :(得分:0)
你可以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).