C Double Free Проблема - PullRequest
       27

C Double Free Проблема

1 голос
/ 16 декабря 2010

Я сталкиваюсь с двойной свободой, и я не вижу, где это происходит.Целью следующего кода является удаление узлов 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 ]

5 голосов
/ 16 декабря 2010

Когда вы освобождаете человека, вы не устанавливаете указатель 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 голос
/ 16 декабря 2010

В функции free_person присваивания NULL на самом деле не нужны, поскольку вы также освобождаете содержащую структуру.В противном случае было бы необходимо предотвратить наличие висящего указателя .

Кроме того, person = NULL назначает только локальный параметр функции, который теряется сразу после ее возврата.

1 голос
/ 16 декабря 2010
void free_person(person *person) {
    /* ... */
    free(person);
    person = NULL;
}

Это только устанавливает локальный person в NULL; нет никакого изменения к человеку на рутине вызова.

...