所以我正在尝试一种方法来清除学校的双向链表,其中双向链表和节点定义为:
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时,我被告知要释放,所以就在那里。
我遇到的问题是,当我运行教授提供的测试文件时,我得到了一个“虚假指针(双重释放?)”和一个核心转储。我已经为此工作了几个小时,似乎无法找出我在哪里(或如何)打了两次免费电话。
答案 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...
也。创建以下节点时进行检查:
答案 2 :(得分:0)
在退出清除功能之前,请不要使p_head
无效。
因此,如果您两次调用它,则会遇到问题(即p_head
指向已释放的节点)。 p_tail
也是如此。
此外,如果您尝试再次添加到列表中,也会遇到类似的问题。
否则,您的清晰代码就可以了。
因此,您可以证明列表是正确的构造吗(例如,在您free
之前,添加一个printf
来打印出所有节点指针 before < / em>您释放任何东西)。