链表中的C free()内存

时间:2016-07-26 17:12:18

标签: c memory linked-list free

我用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;
    }
}

3 个答案:

答案 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 遍历链接列表。