简体   繁体   English

双链表出现双重错误

[英]Double free error with doubly linked list

So I'm trying to do a method to clear a doubly linked list for school where the doubly linked list and nodes are defined as: 所以我试图做一种方法来清除学校的双向链表,其中双向链表和节点定义为:

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

I have a method to clear a linked list by doing 我有一种方法可以通过清除链接列表

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

I do a free() on curr->one_word.unique_word because it's a malloc'd char array. 我对curr-> one_word.unique_word做一个free(),因为它是一个malloc的char数组。 I was taught to free when I use malloc, so that's there. 当我使用malloc时,我被告知要释放,所以就在那里。

The issue I run into is I get a "bogus pointer (double free?)" and a core dump when I run the test file provided by my professor. 我遇到的问题是,当我运行教授提供的测试文件时,我得到了“虚假指针(双重释放?)”和一个核心转储。 I've worked on this for a few hours and can't seem to find out where (or how) I'm calling free twice. 我已经为此工作了几个小时,似乎无法找出我在哪里(或如何)打了两次免费电话。

When you loop through the list, you should constantly change the position of the head, so that even if you repeat clear_linked_list, you will not get an error. 遍历列表时,应不断更改头部的位置,这样即使重复执行clear_linked_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;
    }
}

When freeing memory it is a good practice to set NULL to pointers that were freed to avoid this kind of problems. 释放内存时,将空值设置为已释放的指针以避免这种问题是一种好习惯。 So you should do: 因此,您应该执行以下操作:

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...

Also. 也。 Check that when you create the nodes that: 创建以下节点时检查:

  • *p_next is NULL on the last node of the double linked list * p_next在双链表的最后一个节点上为NULL
  • *p_previous is NULL on the first node of the list * p_previous在列表的第一个节点上为NULL

You don't null out p_head before you leave the clear function. 在离开clear函数之前,请不要使p_head无效。

So, if you called it twice, you'd have problems (ie p_head would point to an already freed node). 因此,如果您两次调用它,将会遇到问题(即p_head将指向已释放的节点)。 Likewise for p_tail . 同样对于p_tail

Also, if you tried to add to the list again, you'd have similar problems. 另外,如果您尝试再次添加到列表中,则会遇到类似的问题。

Otherwise, your clear code is just fine. 否则,您的清晰代码就可以了。

So, can you prove that the list is constructed correctly (eg before you free , add a printf that prints out all the node's pointers before you free anything). 因此,您可以证明该列表是正确构造的吗(例如,在free之前,添加一个printf ,以便释放任何内容之前打印出所有节点的指针)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM