關於malloc和free連結串列節點遇到的問題
阿新 • • 發佈:2021-11-18
連結串列初始化程式碼:
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);//採用此方法呼叫