关于malloc和free链表节点遇到的问题

链表初始化代码:

Node* list_init(void){
    Node *head = (Node *)malloc(sizeof(Node));
    Node *p1 = (Node *)malloc(sizeof(Node));
    Node *p2 = (Node *)malloc(sizeof(Node));
    Node *p3 = (Node *)malloc(sizeof(Node));
    Node *p4 = (Node *)malloc(sizeof(Node));
    Node *p5 = (Node *)malloc(sizeof(Node));
    head->val = -1;
    p1->val = 11;
    p2->val = 5;
    p3->val = 7;
    p4->val = 10;
    p5->val = 1;
    head->next = p1;
    p1->next = p2;
    p2->next = p3;
    p3->next = p4;
    p4->next = p5;
    p5->next = NULL;
    return head;
}

链表删除代码:

void list_deinit(Node* head){
    while(head){
        Node* tmp = head;
        head = head->next;
        free(tmp);
        tmp = NULL;
    }
}

链表打印代码:

void list_print(Node* head){
    int first = 1;
    while (head)
    {
        if(first){
            first=0;
            printf("head->");
        }
        else{
            printf("(%d)->", head->val);
        }       
        head = head->next;
    }
    printf("NULL\n");
}

这时,在主函数中:

Node *head = list_init();
list_deinit(head);
list_print(head);

运行程序会报段错误,疑问点在于:list_print函数中已经加入了head=NULL的特殊情况判断逻辑,但还是在deinit调用之后报错

经过在init和deinit函数中打印链表各节点地址发现,deinit函数中传入的只是head指针的一个副本;因此,在deinit函数中,head指针的副本以及链表其他节点已经全部释放空间并指向了NULL

但是在主函数中,head指针指向的结构体被释放了空间,但是并没有赋值为NULL,因此,在deinit之后再调用list_print,实际上是传入了一个野指针(此时的head),因此报了段错误。

修改后的程序代码源文件如下:

void list_deinit(Node **head)
{
    while (*head)
    {
        Node** tmp = head;
        *head = (*head)->next;
        free(*tmp);
        *tmp = NULL;
    }
}//二级指针方法可以销毁head本身,并不是传入的副本

list_deinit(&head);//采用此方法调用
posted @ 2021-11-18 18:55  Zupernova  阅读(157)  评论(0编辑  收藏  举报