2015-08-16 168 views
1

假設我有一些數據結構,其中結構體具有指向其他結構體(如鏈接列表)的指針。列表中的每個元件都有一個指向另一個元素列表釋放指向其他結構的結構體中的指針

struct node{ 
    char* data; 
    node* next; 
}; 

當釋放分配給這個結構的記憶,我知道我需要專門免費的數據首先,我必須爲它分配內存特別。但接下來呢?它指向另一個節點,我相信釋放它會釋放下一個指向的實際節點。

清理時是否釋放整個節點就足夠了,還是有什麼方法釋放指針而不釋放它指向的結構?

+0

正在刪除一個項目還是整個列表?無論哪種方式,'free()'只釋放它傳遞的指針;它不知道或釋放該結構指向的任何數據。 –

+0

我不明白爲什麼你需要爲'next'分配內存? – ameyCU

+3

不要考慮釋放指針 - 考慮釋放你分配的內存塊。一旦不再需要塊,就可以用空閒來平衡每個分配......可以有一百個指向同一個塊的指針,並且您仍然只需要釋放一次,或者您可以指向您不需要的東西動態分配你根本不需要釋放。 – Dmitri

回答

3

有像沒有東西釋放的指針,你只能免費內存一個指針指向 - 所以,如果你想刪除一個鏈表的一個元素,你必須更新next前一個項目的指針,因此它在刪除之前指向要刪除的元素的next(可能爲NULL)。

void deleteNode(struct node **list, struct node *element) 
{ 
    /* first node? */ 
    if (element == *list) 
    { 
     *list = element->next; 
     free(element->data); 
     free(element); 
     /* now list points to the second element, if any */ 
    } 
    else 
    { 
     /* find previous node */ 
     struct node *p = *list; 
     while (p->next != element) p = p->next; 

     /* adjust next pointer */ 
     p->next = element->next; 
     free(element->data); 
     free(element); 
    } 
} 

注意,在使用單鏈表是不適合與隨機刪除大名單,因爲你必須從一開始每次搜索的列表。

要刪除一個整個鏈表,有一個迭代和遞歸的方法,但我沒有在這裏顯示代碼,因爲根據我的理解你的問題,這不是你想要做的。

4

這取決於你如何在內存中構建結構。任何malloc必須與free平衡。一旦指向next節點被釋放,它不再有效。

// create root 
node* n1 = calloc(1, sizeof(node)); 

// create/link another node 
n1->next = calloc(1, sizeof(node)); 

// destroy/unlink 2nd node 
free(n1->next); 
n1->next = NULL; 

// destroy 1st node 
free(n1);