C 具有双链接列表的双自由错误

C 具有双链接列表的双自由错误,c,linked-list,doubly-linked-list,C,Linked List,Doubly Linked List,因此,我尝试使用一种方法来清除学校的双链接列表,其中双链接列表和节点定义为: struct word_entry { char *unique_word ; int word_count ; } ; struct node { struct word_entry one_word ; struct node *p_previous ; struct node *p_next ; } ; struct linked_list { struct n

因此,我尝试使用一种方法来清除学校的双链接列表,其中双链接列表和节点定义为:

struct word_entry
{
    char *unique_word ;
    int word_count ;
} ;

struct node
{
    struct word_entry one_word ;
    struct node *p_previous ;
    struct node *p_next ;
} ;

struct linked_list
{
    struct node *p_head ;
    struct node *p_tail ;
    struct node *p_current ;
} ;
我有一种方法可以通过执行以下操作来清除链接列表

int clear_linked_list( struct linked_list *p_list ) //return how many nodes were cleared
{
    if (p_list->p_head == NULL) {
        return 0;
    }
    else {
        int count = 0;
        struct node *curr = p_list->p_head;

        while (curr != NULL) {
            struct node *next = curr->p_next;

            free(curr->one_word.unique_word);
            free(curr);
            curr = next;
            count++;
        }

        return count;
    }
}
我对curr->one_word.unique_word执行free()操作,因为它是一个malloc'd字符数组。当我使用malloc时,我被教导自由,所以这就是


我遇到的问题是,当我运行教授提供的测试文件时,我得到了一个“伪指针(双自由度?)和一个内核转储。我已经为此工作了几个小时,似乎无法找到我在哪里(或如何)打了两次免费电话。

当你在列表中循环时,你应该不断改变头部的位置,这样即使你重复clear\u linked\u list,你也不会出错

int clear_linked_list(struct linked_list* p_list)  // return how many nodes were cleared
{
    if (p_list->p_head == NULL) {
        return 0;
    } else {
        int count = 0;
        while (p_list->p_head != NULL) {
            struct node* curr = p_list->p_head;
            p_list->p_head = p_list->p_head->p_next;

            free(curr->one_word.unique_word);
            free(curr);
            count++;
        }

        return count;
    }
}

释放内存时,最好将为避免此类问题而释放的指针设置为NULL。 所以你应该:

free(curr->one_word.unique_word);
curr->one_word.unique_word=NULL; 
//if that one_word.unique_word was shared between multiples nodes that free could cause problems if you dont set it to NULL afterwards
free(curr);
curr=NULL; //or curr=next...
还有。在创建节点时,请检查:

  • *在双链接列表的最后一个节点上,p_next为空
  • *p_previous在列表的第一个节点上为空

在退出清除功能之前,不能将
p\u head
调零

因此,如果调用它两次,就会出现问题(即,
p_head
将指向已释放的节点)。同样适用于
p_tail

此外,如果您再次尝试添加到列表中,您也会遇到类似的问题

否则,您的清晰代码就可以了


因此,您能否证明列表构造正确(例如,在您
free
之前,添加一个
printf
,在您释放任何内容之前打印出所有节点的指针)。

您发布的代码似乎没有编译,由于您访问
p_list->p_next
,但
struct linked_list
没有成员
p_next
。你能再检查一下你发布的代码是否与产生错误的代码相同吗?(如果您可以添加一个很小的
main
函数,使其成为一个函数,那就太好了)哪种语言?C或C++。请选择一个并编辑你问题的标签。对不起@DavidZ,我看错了东西。代码现在应该被修复了。main大约有7k个测试,所以要想知道它是哪一个测试/之前会发生什么有点困难。酷,那更好。顺便说一句,不需要在帖子中添加“编辑:”或对编辑内容的评论,也就是说,你的最后一行可以全部删除,尽管我不认为这是一个足够大的问题,只需要进行一次单独的编辑。你是不是用同一个列表两次调用
clear\u linked\u list
?当你清除它时,你不会重置
p_head
指针,这样它就会指向已经释放的内存。我完全拥有你所拥有的,并且我仍然在free()中得到一个
:伪指针(双空闲?
和一个任意内存地址