C双免费问题

时间:2010-12-15 21:25:17

标签: c struct malloc free

我遇到了双重免费,我无法看到它发生在哪里。以下代码的目标是从链接列表中删除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--;
        }
    }

...

3 个答案:

答案 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仅分配函数的本地参数,该函数在返回后立即丢失。