2014-02-07 27 views
-1

基本上,我有內存泄漏。所以我想解決它們!在某些函數中添加了free()。運行valgrind並獲得成功消息所有泄漏記憶都是固定的或者不正確的!然後我有一堆錯誤:(我認爲我已經把免費()正確的。很容易感到困惑,因爲有節點作爲指針和節點作爲一個結構(看在file.h)任何幫助表示讚賞謝謝。很抱歉,如果這個問題很簡單,我是初學者.....在file.h內存泄漏檢測導致的錯誤

代碼

struct node { 
    int value; 
    struct node * next; 
}; 
typedef struct node List; 

int is_empty(List *); 
List *add_node(List *, int); 
List *remove_node(List *, int); 
List *create_node(int); 
char *tostring(List *); 

代碼file.c

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include "list.h" 

#define STRSIZE 128 /*assume string representation fits*/ 

/* Return true if the list h is empty 
* and false otherwise. 
*/ 
int is_empty(List *h) { 
    return h == NULL; 
} 

/* Create a list node with value v and return a pointer to it 
*/ 
List *create_node(int v) { 
    List *node = malloc(sizeof(List)); 
    free(node); 
    node->value = v; 
    node->next = NULL; 
    return node; 
} 

/* Insert a new node with the value v at the 
* front of the list. Return the new head of 
* the list. 
*/ 
List *add_node(List *h, int v) { 
    List *node = create_node(v); 
    node->next = h; 
    return node; 
} 

/* Remove the first node in the list h that 
* has the value v. Return the head of the 
* list. 
*/ 
List *remove_node(List *h, int v) { 
    List *curr = h; 

    /* Handle the cases when list is empty or the value 
    * is found at the front of the list */ 
    if (h == NULL) { 
     return h; 
    } else if (h->value == v) { 
     h = h->next; 
return h; 
    } 

    /* Look for the value in the list (keeping the pointer to 
    * the previous element so that we can remove the right 
    * element) */ 
    while (curr->next != NULL && curr->next->value != v) { 
     curr = curr->next; 
    } 

    if (curr->next == NULL) { /* v is not in list so do nothing */ 
     return h; 
    } else { /* curr->next->value == v */ 
     curr->next = curr->next->next; 
     return h; 
    } 
} 

/* Return a string representation of the list pointed to by h. 
*/ 
char *tostring(List *h) { 
    char *str= malloc(STRSIZE); 
    char num[4]; /* assume integer has max. four digits*/ 
    free(str); 
    str[0] = '\0'; 
    while (h != NULL) { 
     sprintf(num, "%d", h->value); 
     strncat(str, num, STRSIZE - strlen(str) - 1); 
     h = h->next; 
    } 
    return str; 
} 
+2

修復內存泄漏是剛剛得到充分的理解你的程序的最佳途徑。 – moeCake

回答

1

也許你想

temp = curr->next; 
curr->next = curr->next->next; 
free (temp); 

在你的代碼的當前狀態remove_node是泄漏(實際上泄漏的整個列表,如果刪除了所有的節點)。

此外,爲了阻止tostring函數中的內存泄漏,此函數的調用者有責任釋放由tostring返回的字符串。

0

在功能remove_node

List *remove_node(List *h, int v) 
{ 
List *curr = h,*prev; 

/* Handle the cases when list is empty or the value 
* is found at the front of the list */ 
if (h == NULL) { 
    return h; 
} else if (h->value == v) { 
    h = h->next; 
    free(curr); 
    return h; 
} 

while (curr->next != NULL && curr->next->value != v) { 
    curr = curr->next; 
} 

if (curr->next == NULL) { /* v is not in list so do nothing */ 
    return h; 
} else { /* curr->next->value == v */ 
    prev = curr->next; 
    curr->next = curr->next->next; 
    free(prev); 
    return h; 
} 
} 

您應該釋放的內存時,你不再需要在你的情況下節點同時去除你應該釋放內存的節點。

而且在功能tostring不釋放你只是自由分配在被調用函數的內存後,海峽不再被使用或所需的內存。

+0

嗯,我仍然有內存泄漏的地方......沒有任何錯誤,雖然.... @ KARTHIK每當你使用動態分配(的malloc,realloc的)分配內存所以在您檢查所有已分配 – Manuel

+0

內存泄漏發生在運行時(動態),你必須對所有這些。只有發生內存泄漏的地方使用字符串,因此在釋放節點空閒字符串然後釋放節點之前。 – const

1

在你create_node(),爲什麼你有一個免費的()?你應該刪除那個免費的()。

在你remove_node(),你需要總是返回頭。我認爲下面的遞歸方法應該可以工作。遞歸函數將找到要刪除的節點並返回下一個節點。如果沒有被刪除,它將返回相同的節點。繼續遞歸,直到找到具有值的節點或列表的末尾。檢查主要的是,它在

  1. 取出頭節點
  2. 空單
  3. 刪除最後一個節點
  4. 刪除中間節點

下面的代碼是工作未經測試:-)。

你提到你仍然有內存泄漏。正如Karthik所提到的,你的toString()函數分配內存,並由調用者來釋放它。因此,確保每次調用toString()函數時都會調用free()。否則,你會泄漏內存。

List *remove_node(List *h, int v) { 
    List *retval = remove_recurse(h,v); 

    // if retval is different from head, means head is removed. return new head. 
    // Otherwise return old head. 
    return (retval!=h) ? retval : h; 
} 

List *remove_recurse(List *node, int v) { 
    if(node==NULL) return NULL; 

    List *retval = node; // default return current node 

    if(node!=NULL && node->value==v) { // need to remove node 
     retval = node->next; // return the next node 
     free(node); // delete node 
    } 
    else { 
     List *temp = remove_recurse(node->next,v); 
     // if next node was deleted, point to new node 
     if(node->next!=temp) node->next=temp; 
    } 

    return retval; 
} 
1

有了這個

List *node = malloc(sizeof(List)); 
free(node); 
你分配一個節點(列表)

然後讓節點指向它,那麼你免費哪個節點指向這麼自由後,其在某處指着一些未分配的空間內存然後你開始分配到內存:

node->value = v; 
node->next = NULL; 

這會導致不確定的行爲,這肯定是不對的,但不會由編譯器進行檢測。

刪除free(node)

List *create_node(int v) 
{ 
    List *node = malloc(sizeof(List)); 
    node->value = v; 
    node->next = NULL; 
    return node; 
} 

它是更具可讀性,如果你保持結構的名稱相同的typedef即

typedef struct node {...} node; 

,而不是創建一個新的別名,改用更好的變量名字例如

node* listStartOfNodes = NULL; // always initialize 
1

1,這個功能是錯誤的。

List *create_node(int v) { 
    List *node = malloc(sizeof(List)); 
    free(node); 
    node->value = v; 
    node->next = NULL; 
    return node; 
} 

爲什麼你free(node)?請刪除此free(node);。 而在這個功能同樣的故障,請刪除free(str);

char *tostring(List *h) { 
    char *str= malloc(STRSIZE); 
    char num[4]; /* assume integer has max. four digits*/ 
    free(str); 
    str[0] = '\0'; 
    while (h != NULL) { 
     sprintf(num, "%d", h->value); 
     strncat(str, num, STRSIZE - strlen(str) - 1); 
     h = h->next; 
    } 
    return str; 
} 

2,您應該修改這個功能:

List *remove_node(List *h, int v) { 
    List *curr = h; 
    List* freeNode = NULL; 
    /* Handle the cases when list is empty or the value 
    * is found at the front of the list */ 
    if (h == NULL) { 
     return h; 
    } else if (h->value == v) { 
     freeNode = h; 
     h = h->next; 
     free(freeNode); 
     return h; 
    } 

    /* Look for the value in the list (keeping the pointer to 
    * the previous element so that we can remove the right 
    * element) */ 
    while (curr->next != NULL && curr->next->value != v) { 
     curr = curr->next; 
    } 

    if (curr->next == NULL) { /* v is not in list so do nothing */ 
     return h; 
    } else { /* curr->next->value == v */ 
     freeNode = curr->next; 
     curr->next = curr->next->next; 
     free(freeNode); 
     return h; 
    } 
}