提问人:Celes 提问时间:7/11/2023 最后编辑:Celes 更新时间:7/11/2023 访问量:84
为什么在 c 中有两个临时变量的自由链表?
Why free linked list with two temporary variables in c?
问:
我正在学习 CS50 课程,最后一部分代码是由讲师编写的,用于释放使用的内存:
ptr = list;
while (ptr != NULL)
{
node *next = ptr->next;
free(ptr);
ptr = next;
}
我知道需要将 next 用作临时指针,但为什么“ptr”(指向链表“列表”开头的原始指针的临时点)用于释放内存?有什么理由不直接使用“列表”吗?
while (list != NULL)
{
node *next = list->next;
free(list);
list = next;
}
我试着这样做,它似乎也一样;对直接释放列表有什么顾虑吗?
答:
tl;博士 是的,你可以直接使用 list,只要while (list != NULL)
内存泄漏
是的,这两者非常不同。第二种实现会导致内存泄漏。
内存泄漏是像 c 这样的低级语言中一个非常常见的错误,正是因为你的程序“似乎工作得一样”。事实上,你可以简单地做,程序仍然可以工作(尽管不能正常工作)。但是,如果不调用,内存就会占用。此外,您已经失去了对指针的跟踪,因此以后无法释放内存。这是内存泄漏。如果只是一个小小的泄漏,就不会发生任何不好的事情。在一个大型程序中,它会占用您计算机的 RAM。您可以通过多次调用并检查程序的内存使用情况来尝试此操作。list = NULL
free
malloc
另请查看 在程序终止之前,当您在 malloc 之后不释放时,会发生什么?
您的代码
如果你的意思是而不是那么我很确定你的代码是正确的,你可以直接使用(我只是意识到你可能在输入了之前的所有解释😭后打错了字)。教师可能已选择使用额外的变量,以便与他们在其他函数中遍历链表的方式保持一致。while (list != NULL)
while (ptr != null)
list
ptr
ptr
但是以您现在所拥有的,代码相当于一行 .除了第一个元素之外,任何元素都不会被释放。free(list);
P.S. 您可以使用以下命令检查内存泄漏(不适用于 mingw)。gcc -fsanitize=address program.c
评论
在 CS50x 2023 - 第 5 讲 - 数据结构的 1:22:00(1 小时 22 分钟)左右,将显示此代码。
临时节点之所以存在,仅仅是因为讲师使用它来首先打印列表的内容,而不会丢失对根节点(本身)的跟踪。ptr
list
node *ptr = list;
while (ptr != NULL)
{
printf("%i\n", ptr->number);
ptr = ptr->next;
}
在此循环之后,是 .ptr
NULL
ptr
然后,在释放所有节点的循环中重复使用(再次设置为 beforehand),如第一个代码片段所示。list
这纯粹是一种风格选择 - 如果你不关心保留它所持有的价值,你也可以使用(之后无用)。事实上,在前一年的讲座中(~ CS50 2021 中的 1:07:00 HDR - 第 5 讲 - 数据结构),代码list
free
while (list != NULL)
{
node *tmp = list->next;
free(list);
list = tmp;
}
被使用,它就是这样做的。
上一个:我怎样才能同时返回和释放内存
评论
ptr
while (list != NULL)