2010-12-15 104 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只分配返回后丢失的函数的本地参数。