我想知道为什么自由列表是递归函数,并且在做什么
typedef struct listint_s
{
char *a;
char *b;
struct listint_s *next;
} listint_t;
void free_list(listint_t *head)
{
if (head)
{
if (head->next)
free_list(head->next);
free(head->a);
free(head);
}
}
答案 0 :(得分:0)
此处的递归用于对列表的每个元素进行免费调用。对free_list的第一个调用是处理头节点。第二个调用在head-> next上运行,依此类推。注意,只有在调用free_list(head-> next)后 后才释放输入节点。如果不是这种情况,则链接列表将无法释放head之后的元素。
使用while循环而不是递归可以完成相同的事情:
{
listint_t *next;
while (head)
{
next = head->next;
free(head);
head = next;
}
return;
}
答案 1 :(得分:0)
如果您想知道free()
本身的功能,请查看How malloc and free work。关于free_list()
:
这是一个递归函数,因为链表(listin_s
是)的结构是递归的。即*next
本身就是listint_s
。因此,它适合于递归操作。只是我们可以将结构定义为“一个包含两个char *的东西,以及一个指向列表其余部分的指针”,我们可以将freeing的操作定义为“释放列表的其余部分,然后释放具有两个内容的那个东西” char *和指向列表其余部分的指针”。带注释:
void free_list(listint_t *head)
{
if (head) // If this thing is not null
{
if (head->next) // If the rest of the list is not null (i.e. we have not reached the end of the list yet)
free_list(head->next); // Free the rest of the list
free(head->a); // Then, free the thing pointed to by *a (note for some reason we are not freeing b?)
free(head); // Then, free this thing
}
}
答案 2 :(得分:0)
这将释放列表中的所有节点,以及它们从其a
成员(但不是b
成员)指向的节点。
递归调用首先遍历列表节点,直到到达其head->next
元素为NULL
的节点为止。
在每个递归调用中,head
指向当前元素。递归调用返回后,它将释放head->a
指向的内容,然后使用free(head);
释放当前元素。
测试if (head->next)
是多余的,因为free_list()
使用if (head)
检查是否在空指针上调用了它。
大多数人迭代而不是递归地编写这种循环,因为在尝试释放一个很长的列表时可能会出现堆栈溢出。
while (head) {
free(head->a);
listint_s *temp = head;
head = head->next;
free(temp);
}