双链表出现双重错误

时间:2018-10-13 02:12:41

标签: 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 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的char数组。当我使用malloc时,我被告知要释放,所以就在那里。

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

3 个答案:

答案 0 :(得分:0)

遍历列表时,应不断更改头部的位置,这样即使重复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;
    }
}

答案 1 :(得分:0)

释放内存时,将空值设置为已释放的指针以避免这种问题是一种好习惯。 所以你应该这样做:

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在双链表的最后一个节点上为NULL
  • * p_previous在列表的第一个节点上为NULL

答案 2 :(得分:0)

在退出清除功能之前,请不要使p_head无效。

因此,如果您两次调用它,则会遇到问题(即p_head指向已释放的节点)。 p_tail也是如此。

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

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

因此,您可以证明列表是正确的构造吗(例如,在您free之前,添加一个printf来打印出所有节点指针 before < / em>您释放任何东西)。