释放c中的单向链表
Freeing a singly linked list in c
我在实现单向链表时遇到了一个奇怪的问题。我调用 list_destroyer 并将指针传递给列表的头部,但是当方法 returns 时,传递的指针仍然指向完整列表。我不相信我在任何地方都传递了结构。
这是我的结构列表,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 输出显示大小正在减小。 "head = NULL;" 语句周围的两个 printf 都打印出大小为零。 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_t 之后的 printf 如何=26=] 仍然会输出 2,(尤其是当 list_destroy 中的 printf 表示传入的 list_t* 最后的大小为 0 时。
however when the method returns, the pointer that is passed still points to a full list.
这是不正确的:当函数 returns 时,指针指向曾经是完整列表的内容。很有可能,您的系统会让您不间断地遍历整个列表。但是,在调用后取消引用此指针是 未定义的行为,因此相同的代码可能会在其他系统上崩溃。
这个问题有一个名字 - 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;
}
我在实现单向链表时遇到了一个奇怪的问题。我调用 list_destroyer 并将指针传递给列表的头部,但是当方法 returns 时,传递的指针仍然指向完整列表。我不相信我在任何地方都传递了结构。
这是我的结构列表,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 输出显示大小正在减小。 "head = NULL;" 语句周围的两个 printf 都打印出大小为零。 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_t 之后的 printf 如何=26=] 仍然会输出 2,(尤其是当 list_destroy 中的 printf 表示传入的 list_t* 最后的大小为 0 时。
however when the method returns, the pointer that is passed still points to a full list.
这是不正确的:当函数 returns 时,指针指向曾经是完整列表的内容。很有可能,您的系统会让您不间断地遍历整个列表。但是,在调用后取消引用此指针是 未定义的行为,因此相同的代码可能会在其他系统上崩溃。
这个问题有一个名字 - 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;
}