C在链表中释放()内存

C在链表中释放()内存,c,memory,linked-list,free,C,Memory,Linked List,Free,我用1->2->3打印了一个单链表。然后我尝试使用free(head)来释放head的内存,我得到了0->2->3作为输出 我想知道为什么释放内存后头部节点的*下一个仍然存在。当我传递到print函数时,我认为*头中应该什么都没有了 对不起,我是C和内存管理新手。如果可能的话,请帮我一些提示 #include <stdio.h> #include <stdlib.h> struct ListNode{ int val; struct ListNode *

我用
1->2->3
打印了一个单链表。然后我尝试使用
free(head)来释放head的内存,我得到了
0->2->3
作为输出

我想知道为什么释放内存后头部节点的
*下一个
仍然存在。当我传递到
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;
    }
}
#包括
#包括
结构列表节点{
int-val;
结构ListNode*next;
}列表节点;
void addNode(结构列表节点*头,int val);
void printNode(结构列表节点*头);
结构ListNode*deleteNode(结构ListNode*head,int val);
int main(int argc,字符**argv){
结构ListNode*头;
head=(struct ListNode*)malloc(sizeof(struct ListNode));
head->val=1;
addNode(头部,2);
addNode(头,3);
//测试A:打印链表值:1 2 3
打印节点(头);
printf(“\n”);
//测试B:可用内存:0 2 3
结构ListNode*cur=head;
自由(头);
打印节点(头);
返回0;
}
void addNode(结构列表节点*头,int val){
结构ListNode*cur=head;
while(cur->next){
cur=cur->next;
}
结构ListNode*t;
t=(struct ListNode*)malloc(sizeof(struct ListNode));
t->val=val;
cur->next=t;
}
void printNode(结构ListNode*头){
结构ListNode*cur=head;
while(cur){
printf(“%d”,cur->val);
cur=cur->next;
}
}

您还需要从addNode()函数中释放分配的节点,而不仅仅是头节点。作为新手,开始学习使用valgrind检查内存泄漏。坚持下去。

您还需要从addNode()函数中释放分配的节点,而不仅仅是头节点。作为新手,开始学习使用valgrind检查内存泄漏。坚持下去。

您只引用链接列表的标题,而不是整个链接列表。您需要遍历列表并单独释放每个组件

这应该对代码有帮助:

您只引用链接列表的标题,而不是整个链接列表。您需要遍历列表并单独释放每个组件

这应该对代码有帮助:

malloc库有自己的缓冲。当我们要求一个随机大小的缓冲区时,它将大小包装到预定义的大小(通常是2的次幂),并为我们分配一个包装大小的预先分配的内存块

类似地,当我们释放一个缓冲区时,记忆不会消失(与我们的感知相反)。内存块被标记为“空闲缓冲区”。然后,该缓冲区用于后续合适的请求

在您的例子中,同样的情况也发生了,头部的值字段被归零,但下一个字段保持不变。如果你写这样的东西

free(head);
for(i = 0; i < 1000; i++) {
    ptr = malloc(<some random size>);
    free(ptr);
}
printNode(head);
free(头部);
对于(i=0;i<1000;i++){
ptr=malloc();
免费(ptr);
}
打印节点(头);
它很可能导致缓冲区被重用,从而导致缓冲区被垃圾数据填满


在这种情况下,您将无法使用head遍历链表。

malloc库自行进行缓冲。当我们要求一个随机大小的缓冲区时,它将大小包装到预定义的大小(通常是2的次幂),并为我们分配一个包装大小的预先分配的内存块

类似地,当我们释放一个缓冲区时,记忆不会消失(与我们的感知相反)。内存块被标记为“空闲缓冲区”。然后,该缓冲区用于后续合适的请求

在您的例子中,同样的情况也发生了,头部的值字段被归零,但下一个字段保持不变。如果你写这样的东西

free(head);
for(i = 0; i < 1000; i++) {
    ptr = malloc(<some random size>);
    free(ptr);
}
printNode(head);
free(头部);
对于(i=0;i<1000;i++){
ptr=malloc();
免费(ptr);
}
打印节点(头);
它很可能导致缓冲区被重用,从而导致缓冲区被垃圾数据填满


在这种情况下,您将无法使用head遍历链表。

在指针指向的对象的生存期结束后使用指针值的未定义行为。顺便说一句,成员的next
未初始化。(
head->next
t->next
)无关,无论您是否意识到,您的
struct ListNode
声明还声明了一个名为
ListNode
的全局变量。非常确定您的意图是在所有这些之前使用
typedef
谢谢您的评论!我真的从你们身上学到了很多!在指针指向的对象的生存期结束后使用指针值的未定义行为。顺便说一句,成员的下一步未初始化。(
head->next
t->next
)无关,无论您是否意识到,您的
struct ListNode
声明还声明了一个名为
ListNode
的全局变量。非常确定您的意图是在所有这些之前使用
typedef
谢谢您的评论!我真的从你们身上学到了很多!