我遇到了双重免费,我无法看到它发生在哪里。以下代码的目标是从链接列表中删除Person节点。
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--;
}
}
...
答案 0 :(得分: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;
答案 1 :(得分:1)
void free_person(person *person) {
/* ... */
free(person);
person = NULL;
}
这只将本地person
设置为NULL;呼叫程序中的人没有变化。
答案 2 :(得分:1)
在free_person
函数中,NULL
的赋值并不是必需的,因为您也释放了包含结构。否则,有必要防止dangling pointer。
此外,person = NULL
仅分配函数的本地参数,该函数在返回后立即丢失。