[英]Freeing a singly linked list in c
在实现单链表时,我遇到了一个似乎很奇怪的问题。 我调用list_destroyer并将指针传递给列表的头部,但是当方法返回时,传递的指针仍然指向完整列表。 我不相信我已经在任何地方传递了一个结构。
这是我的结构列表和typedef
typedef struct list list_t
struct list{
void* datum;
list_t* next;
};
这是导致问题的代码
void list_destroy(list_t *head){
list_t *destroy = head;
while(head){
//printf("%d \n", list_size(head));
head = head->next;
free(destroy);
destroy = head;
}
//printf("%d \n", list_size(head));
head = NULL;
//printf("%d \n", list_size(head));
}
list_size函数已被注释掉,因为它们不是必需的,但我使用它们来查看代码的输出。 printf输出显示大小正在减小。 两个printf围绕着“head = NULL;” 声明都打印大小为零。 这也通过gdb确认。 但是,当我有这个代码(跟随)调用list_destroy时,传递的指针不变。
int main(){
list_t *test = NULL;
int a = 1;
int b = 2;
list_append(test,&a);
list_append(test,&b);
printf("%d \n", list_size(test));
list_destroy(test);
printf("%d \n", list_size(test));
}
我仍然得到list_destroy上面和下面的printf两个输出2.我没有在任何地方初始化一个新的list_t,所以我没有看到list_destroy之后的printf如何仍然输出2,(特别是当list_destroy中的printf时)说传入的list_t *最后的大小为0。
但是当方法返回时,传递的指针仍然指向完整列表。
这是不正确的:当函数返回时,指针指向曾经是完整列表的内容。 有可能,您的系统会让您不间断地遍历整个列表。 但是,在调用之后取消引用此指针是未定义的行为 ,因此相同的代码可能会在其他系统上崩溃。
问题有一个名字 - head
成为一个悬垂的指针 。
修复问题很简单 - 将指针传递给指针,并在完成时将其设置为NULL
:
void list_destroy(list_t **headPtr){
list_t *head = *headPtr;
list_t *destroy = head;
while(head){
head = head->next;
free(destroy);
destroy = head;
}
*headPtr = NULL;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.