2010-12-15 106 views
1

我遇到了雙免費,我看不到它發生在哪裏。以下代碼的目標是從鏈接列表中刪除Person節點。C雙免費問題

typedef struct person { 
    char *first ; 
    char *last ; 
    char *location ; 
    struct person *next_person ; 
} person ; 

struct person_list { 
    int num_persons ; 
    person *first_person ; 
} person_list ; 

extern struct person_list person_list ; 

void free_person(person *person) { 
    free(person->first); 
    person->first = NULL; 

    free(person->last); 
    person->last = NULL; 

    free(person->location); 
    person->location = NULL; 

    free(person); 
    person = NULL; 
} 

... 

    if (person_list.num_persons > 0) { 
     while (person_list.num_persons > 0) { 
      //Iterate to the end of the chain. 
      cur_person = person_list.first_person; 

      while (cur_person->next_person != NULL) { 
       cur_person = cur_person->next_person; 
      } 

      free_person(cur_person); 
      person_list.num_persons--; 
     } 
    } 

... 

回答

5

當你自由的人,你不上一人的next_person指針設置爲NULL。因此,它指出釋放的記憶,這就是爲什麼你是雙重釋放。

您需要跟蹤剛要釋放的人之前的人,並將其next_person指針設置爲NULL

另一種更有效的方式來寫你的循環將是以下,這是不是受到同樣的錯誤:

// Grab the first person 
    cur_person = person_list.first_person; 

    // Make sure there is someone to free 
    while (cur_person != NULL) { 
     // Keep track of who to free next 
     nxt_person = cur_person->next_person; 

     free_person(cur_person); 

     // Get the next person in line 
     cur_person = nxt_person; 
    } 

    // Didn't we just remove them all? Yes, we did. 
    person_list.num_persons = 0; 
    // Let's not forget to set that we have no one left 
    person_list.first_person = NULL; 
+0

但是free_person將該人設置爲NULL。爲什麼這不起作用? – Mike 2010-12-15 21:30:59

+2

由於pmg寫道,它只設置函數內的本地副本。你需要在函數之外將它設置爲NULL,或者傳遞一個引用(這是一個C++特性,而不是C)。 – Wolf 2010-12-15 21:33:59

+0

有道理。謝謝! – Mike 2010-12-15 21:34:16

1
void free_person(person *person) { 
    /* ... */ 
    free(person); 
    person = NULL; 
} 

這隻能設置本地person爲NULL;調用例程上的人沒有變化。

1

free_person函數中,NULL的賦值並不是真的必要的,因爲您也釋放了包含結構。否則,有必要防止出現dangling pointer

此外,person = NULL只分配返回後丟失的函數的本地參數。