C 双重自由问题

C 双重自由问题,c,struct,malloc,free,C,Struct,Malloc,Free,我遇到了双重自由,我看不到它在哪里发生。以下代码的目标是从链接列表中删除人员节点 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

我遇到了双重自由,我看不到它在哪里发生。以下代码的目标是从链接列表中删除人员节点

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--;
        }
    }

...

释放此人时,不会将前一个人的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;

释放此人时,不会将前一个人的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;
这只会将本地人员设置为空;呼叫例行程序中的人员没有变化

这只会将本地人员设置为空;调用例程中的person没有变化。

在free_person函数中,赋值为NULL实际上是不必要的,因为您也在释放包含的结构。否则,就有必要防止发生冲突

此外,person=NULL只分配函数的局部参数,该参数在返回后立即丢失。

在free_person函数中,分配到NULL实际上是不必要的,因为您正在释放包含的结构。否则,就有必要防止发生冲突


此外,person=NULL仅分配函数的本地参数,该参数在返回后立即丢失。

但free\u person将该参数设置为NULL。为什么不起作用呢?正如pmg所写的,它只在函数内部设置本地副本。您需要将其设置为函数外的NULL,或者传递一个C++特性的引用,而不是C.我在代码中仍然有一个双删除错误。这可能是因为腐败吗?确保在自由人身上,你释放的所有东西都不是空的。检查person是否为NULL,然后在释放它之前检查person->first是否为NULL,依此类推。也许你从来没有分配过person->first和al。但是free_person将该person设置为NULL。为什么不起作用呢?正如pmg所写的,它只在函数内部设置本地副本。您需要将其设置为函数外的NULL,或者传递一个C++特性的引用,而不是C.我在代码中仍然有一个双删除错误。这可能是因为腐败吗?确保在自由人身上,你释放的所有东西都不是空的。检查person是否为NULL,然后在释放它之前检查person->first是否为NULL,依此类推。也许你从来没有分配过person->first和al。