[英]Why doesn't valgrind detect memory leaks?
我试图弄清楚为什么当我故意避免释放 memory 时valgrind
没有检测到任何错误。 我有这个小程序。 它从键盘读取数字并打印消息You've entered <number>!
. 如果之前已阅读过该号码,则打印You've already read <number>!
.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
struct node {
int number;
struct node* next;
};
struct node* add(struct node* head, int number) {
struct node* n;
struct node* p;
n = (struct node*)malloc(sizeof(struct node));
n->number = number;
n->next = NULL;
if (head == NULL) {
return n;
}
p = head;
while (p->next != NULL) {
p = p->next;
}
p->next = n;
return head;
}
void clear(struct node* head) {
if (head == NULL) {
return;
}
clear(head->next);
free(head);
}
int already_read(struct node* head, int number) {
struct node* p;
if (head == NULL) {
return 0;
}
p = head;
while (p!=NULL && p->number!=number) {
p = p->next;
}
if (p == NULL) {
return 0;
}
return 1;
}
int main(int argc, char** argv) {
int number;
struct node* head = NULL;
while (scanf("%d", &number) == 1) {
if (already_read(head, number)) {
printf("You've already entered %d!\n", number);
}
else {
head = add(head, number);
printf("You entered %d!\n", number);
}
}
clear(head);
return 0;
}
I compiled it using gcc (This file is called program.c
on my system, so I used the command gcc -Wall -g -o program program.c
). 它编译得很好。 然后,当我使用 valgrind ( valgrind./program
) 运行它时,我输入一些数字以查看程序是否正常工作,然后使用CTRL-C
停止它。 我没有错误。 伟大的。
LEAK SUMMARY:
definetely lost: 0 bytes in 0 blocks
indirectly lost: 0 bytes in 0 blocks
possibly lost: 0 bytes in 0 blocks
still reachable: 64 bytes in 4 blocks
suppressed: 0 bytes in 0 blocks
ERROR SUMMARY: 0 errors from 0 context (suppressed: 8 from 6)
然后我 go 回到代码中。 我将所有内容保持原样,除了我将main()
中读取clear(head)
的行更改为//clear(head)
。 所以现在程序不再释放空间了。 它有泄漏。 我用valgrind
重新编译并再次运行它。 我输入与以前相同的输入。 而且...我得到相同的错误报告。 和上面那个完全一样。 我不明白为什么会这样。 它不应该报告 memory 泄漏,因为我没有释放 memory 吗? 难道我做错了什么?
如果我在 clear call 注释掉的情况下运行代码并输入 1, 2, 3, 2, q 那么我得到
==60380== 48 (16 direct, 32 indirect) bytes in 1 blocks are definitely lost in loss record 2 of 2
==60380== at 0x4839755: malloc (vg_replace_malloc.c:307)
==60380== by 0x401178: add (test.c:14)
==60380== by 0x401335: main (test.c:63)
==60380==
==60380== LEAK SUMMARY:
==60380== definitely lost: 16 bytes in 1 blocks
==60380== indirectly lost: 32 bytes in 2 blocks
==60380== possibly lost: 0 bytes in 0 blocks
==60380== still reachable: 0 bytes in 0 blocks
==60380== suppressed: 0 bytes in 0 blocks
命令valgrind --leak-check=full./test
这正是我所期望的。 这是在 amd64 上,所以每个节点都是 16 个字节。 分配了 3 个节点(用于 1、2 和 3,但不用于重复的 2 或 q)。 在main()
结束时, head
变量从 scope 中消失。 所以在终止时不存在指向头(1)节点的指针->这是一个明确的泄漏。 由于链表,确实存在指向 (2) 和 (3) 节点的指针(从头节点到 (2) 和从 (2) 到 (3) 的指针。因此 (2) 和 (3) 节点是间接泄漏。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.