0

i want to know why the free list is a recursive function and what is doing

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);
    }
}

3 Answers3

0

The recursion here is used to call free on every element of the list. The first call to free_list is to process the head node. The second call operates on head->next, and so on. Note the input node is only freed after calling free_list(head->next). If this was not the case, the linked list would not be able to free the elements following head.

The same thing could be accomplished using a while loop instead of the recursion:

{
    listint_t *next;
    while (head)
    {
        next = head->next;
        free(head);
        head = next;
    }
    return;
}
ler
  • 11
  • 1
0

If you want to know what free() itself does, check out How malloc and free work. As to free_list():

It is a recursive function because the structure of a linked list (which listin_s is) is recursive. I.e. *next is itself a listint_s. Therefore, it lends itself to being operated on recursively. Just was we can define the struct as "a thing containing two char*, and a pointer to the rest of the list", we can define the operation of freeing as "free the rest of the list, then free this thing which has two char* and a pointer to the rest of the list". Annotated:

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
    }
}
MyStackRunnethOver
  • 4,872
  • 2
  • 28
  • 42
0

This is freeing all the nodes in the list, and also what they point to from their a members (but not the b members).

The recursive calls first step through the list nodes until it reaches a node whose head->next element is NULL.

Within each recursive call, head points to the current element. After the recursive call returns, it frees what head->a points to and then frees the current element with free(head);.

The test if (head->next) is redundant, since free_list() checks whether it's called on a null pointer with if (head).

Most people write this kind of loop iteratively rather than recursively, as you could get a stack overflow when trying to free a really long list.

while (head) {
    free(head->a);
    listint_s *temp = head;
    head = head->next;
    free(temp);
}
Barmar
  • 741,623
  • 53
  • 500
  • 612