我用1->2->3
打印出一个单链表。然后我尝试使用free(head);
释放头部记忆,我得到0->2->3
作为输出。
我想知道为什么在释放内存后头节点的*next
仍然存在。当我转到*head
函数时,我认为print
中应该没有任何内容。
抱歉,我是C和内存管理的新手。如果可能的话,请帮我一些提示。
#include <stdio.h>
#include <stdlib.h>
struct ListNode{
int val;
struct ListNode *next;
} ListNode;
void addNode(struct ListNode *head, int val);
void printNode(struct ListNode *head);
struct ListNode* deleteNode(struct ListNode* head, int val);
int main(int argc, char **argv){
struct ListNode* head;
head = (struct ListNode*)malloc(sizeof(struct ListNode));
head->val = 1;
addNode(head, 2);
addNode(head, 3);
//test A: print the linked list value: 1 2 3
printNode(head);
printf("\n");
//test B: free memory : 0 2 3
struct ListNode* cur = head;
free(head);
printNode(head);
return 0;
}
void addNode(struct ListNode *head, int val){
struct ListNode* cur = head;
while(cur->next){
cur = cur->next;
}
struct ListNode* t;
t = (struct ListNode*)malloc(sizeof(struct ListNode));
t->val = val;
cur->next = t;
}
void printNode(struct ListNode *head){
struct ListNode* cur = head;
while(cur){
printf("%d ", cur->val);
cur = cur->next;
}
}
答案 0 :(得分:0)
您还需要从addNode()函数释放已分配的节点,而不仅仅是头节点。作为一个新手,开始学习使用valgrind来检查内存泄漏。保持。 Valgring quick start
答案 1 :(得分:0)
您只引用链接列表的头部,而不是整个链接列表。您需要遍历列表并单独释放每个组件。
这应该有助于代码:
LinkedList - How to free the memory allocated using malloc
答案 2 :(得分:0)
malloc库有自己的缓冲。当我们要求一个随机大小的缓冲区时,它会将大小包装到一个预定义的大小(通常是2的下一个幂)并且为我们分配一个预先分配的大小的内存块。
类似地,当我们释放缓冲区时,内存不会被消除(与我们的感知相反)。内存块只标记为“空闲缓冲区”。然后将此缓冲区用于后续合适的请求。
在您的情况下,同样的情况发生, head 的 value 字段已归零,但 next 字段保持不变。如果你写这样的话,
free(head);
for(i = 0; i < 1000; i++) {
ptr = malloc(<some random size>);
free(ptr);
}
printNode(head);
它很可能导致缓冲区被重用,导致缓冲区被垃圾数据填充。
在这种情况下,您将无法使用 head 遍历链接列表。