【发布时间】:2018-10-22 05:37:43
【问题描述】:
我正在尝试实现一个存储非负整数的链表。我的实现如下所示:
我对内存泄漏很好奇,所以我尝试了这个名为 Valgrind 的工具,使用命令“valgrind --leak-check=yes”。
==2540== error calling PR_SET_PTRACER, vgdb might block
==2540== Invalid write of size 4
==2540== at 0x10875E: node_create (in LinkedList/bin/main)
==2540== by 0x108832: list_append (in LinkedList/bin/main)
==2540== by 0x108920: main (in LinkedList/bin/main)
==2540== Address 0x522d098 is 0 bytes after a block of size 8 alloc'd
==2540== at 0x4C2FB0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==2540== by 0x10874B: node_create (in LinkedList/bin/main)
==2540== by 0x108832: list_append (in LinkedList/bin/main)
==2540== by 0x108920: main (in LinkedList/bin/main)
.
.
.
==2540== Invalid read of size 4
==2540== at 0x1088BA: list_pop (in LinkedList/bin/main)
==2540== by 0x1089E1: main (in LinkedList/bin/main)
==2540== Address 0x522d138 is 0 bytes after a block of size 8 alloc'd
==2540== at 0x4C2FB0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==2540== by 0x10874B: node_create (in LinkedList/bin/main)
==2540== by 0x108832: list_append (in LinkedList/bin/main)
==2540== by 0x108942: main (in LinkedList/bin/main)
.
.
.
==2540== HEAP SUMMARY:
==2540== in use at exit: 0 bytes in 0 blocks
==2540== total heap usage: 10 allocs, 10 frees, 584 bytes allocated
==2540==
==2540== All heap blocks were freed -- no leaks are possible
对应的功能是这样实现的:
struct Node {
struct Node* next;
int value;
};
struct List {
struct Node* head;
};
typedef struct Node* Node;
typedef struct List* List;
Node node_create(int value, Node nextNode) {
if(value < 0) {
printf("Error: Could not create node, value is negative.\n");
return NULL;
}
Node node = malloc(sizeof(Node));
if(node != NULL)
{
node->value = value;
node->next = nextNode;
} else {
printf("Error: Could not create node, malloc returned NULL.\n");
}
return node;
}
int list_append(List listHandle, int value) {
Node current = listHandle->head;
Node new = node_create(value, NULL);
if(new == NULL) {
return -1;
}
if(current == NULL) {
listHandle->head = new;
} else {
while(current->next != NULL) {
current = current->next;
}
current->next = new;
}
return value;
}
int list_pop(List listHandle) {
if(listHandle->head == NULL) {
printf("Error: Trying to pop an empty list.\n");
return -1;
}
Node temp = listHandle->head;
int value = temp->value;
if(temp->next == NULL)
{
listHandle->head = NULL;
} else {
listHandle->head = temp->next;
}
free(temp);
return value;
}
我做错了什么?如何改进代码?这甚至是一个问题还是 Valgrind 只是过于迂腐?
【问题讨论】:
-
用
-ggdb重新编译行号并显示完整代码,包括main -
因为你的
typedef,sizeof(Node)实际上是sizeof(Node*),所以你没有为struct Node分配足够的内存。 -
永远不要将指针指向看起来不像指针的东西。
-
@Fredrik 非常感谢,这就是问题所在。我会吸取教训,以后再也不使用 typedef 指针了 ;)
-
您刚刚演示了为什么Is it a good idea to typedef pointers 说“不,除了(也许)函数指针”。
标签: c linked-list valgrind