C语言 双自由错误与双向链表



所以我正在尝试一种方法来清除学校的双向链表,其中双向链表和节点定义为:

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 char数组。当我使用 malloc 时,我被教导要自由,所以就在那里。

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

当你循环浏览列表时,你应该不断改变头部的位置,这样即使你重复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;
}
}

释放内存时,最好将 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 在双链表的最后一个节点上为 NULL,这是
  • *p_previous 在列表的第一个节点上为 NULL,则为 NULL

在离开清除函数之前,您不会p_head清空。

因此,如果您调用两次,则会遇到问题(即p_head将指向一个已经释放的节点(。同样对于p_tail.

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

否则,您的明文代码就可以了。

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

相关内容

  • 没有找到相关文章

最新更新