2016-02-15 74 views
0

我找不出爲什麼我的鏈表有內存泄漏。C鏈表內存泄漏

我有一種方法稱爲insertAtFront()

void insertAtFront(Node **head, char *key) { 
    Node *new = malloc(sizeof(Node)); 
    if (!new) fatal("Malloc of new Node failed"); 
    new->word = key; 
    new->next = *head; 
    *head = new; 
} 

然後,我有一個removeAtFront()方法釋放的節點。

void removeAtFront(Node **head) { 
    Node *newhead = (*head)->next; 
    free(*head); 
    *head = newhead; 
} 

如果我只添加一個節點,然後刪除它,沒有泄漏。如果我刪除了多個節點,valgrind會顯示與添加了多少個附加節點成比例的泄漏。我真的不明白爲什麼會在節點釋放時發生這種情況。有任何想法嗎?

+0

沒有足夠的代碼顯示評論。您需要顯示如何/何時/何地調用這些方法。 – John3136

+2

請提供顯示問題的代碼的[最小完整且可驗證的示例](https://stackoverflow.com/help/mcve)。從這個不完整的代碼中不可能知道問題是什麼。 – kaylum

+1

注意:'Node * newhead =(* head) - > next;'不應該發生'* head == NULL'。 – chux

回答

3

你的問題似乎是一個生命週期問題。您沒有發佈調用代碼和完整的可驗證示例。節點被正確釋放,但有些事情不是。是否分配了key參數並且沒有在其他地方釋放?

當您釋放節點時,您不需要freeword成員。如果key參數是由調用insertAtFront()的函數分配的,則它應該與節點一起釋放。如果僅爲word字段分配一些時間,則很難確定何時釋放它。

一個很好的解決方案是insertAtFont()總是重複key字符串和removeAtFront()總是釋放word成員:

void insertAtFront(Node **head, const char *key) { 
    Node *new = malloc(sizeof(*new)); 
    if (!new) fatal("Malloc of new Node failed"); 
    new->word = strdup(key); 
    if (!new->word) fatal("Malloc of Node key failed"); 
    new->next = *head; 
    *head = new; 
} 

void removeAtFront(Node **head) { 
    Node *node = *head; 
    if (node) { 
     *head = node->next; 
     free(node->word); 
     free(node); 
    } 
} 

注意,這可能是方便insertAtFront()的指針返回到新插入的節點免費。

+0

你怎麼知道'key'是動態分配的而沒有看到更完整的代碼片段? – John3136

+0

@ John3136:我不知道*,我做了一個假設,寫了*似乎是*。對目標生命週期不準確是一個常見的問題,症狀與我的建議一致。讓我們看看OP是否證實了這一點。我修改了答案,指出了此建議解決方案背後的推理。 – chqrlie

+0

謝謝chqrlie!釋放這個詞似乎就是這樣做的。對不起,所有的代碼缺乏,我只是試圖拉出造成問題的部分。 – user3784695