C: Как освободить узлы в связанном списке?

Как я освобожу узлы, выделенные в другой функции?

struct node {
    int data;
    struct node* next;
};

struct node* buildList()
{
    struct node* head = NULL;
    struct node* second = NULL;
    struct node* third = NULL;

    head = malloc(sizeof(struct node));
    second = malloc(sizeof(struct node));
    third = malloc(sizeof(struct node));

    head->data = 1;
    head->next = second;

    second->data = 2;
    second->next = third;

    third->data = 3;
    third->next = NULL;

    return head;
}  

Я вызываю функцию buildList в main()

int main()
{
    struct node* h = buildList();
    printf("The second element is %d\n", h->next->data);
    return 0;
}  

Я хочу освободить начальную, вторую и третью переменные.
Спасибо.

Обновление:

int main()
{
    struct node* h = buildList();
    printf("The element is %d\n", h->next->data);  //prints 2
    //free(h->next->next);
    //free(h->next);
    free(h);

   // struct node* h1 = buildList();
    printf("The element is %d\n", h->next->data);  //print 2 ?? why?
    return 0;
}

Обе печати 2. Не нужно вызывать free (h) удалить h. Если да, то почему это h- > next- > данные доступны, если h является бесплатным. Конечно, "второй" node не освобождается. Но поскольку головка удалена, она должна иметь возможность ссылаться на следующий элемент. Какая ошибка здесь?

Ответы

Ответ 1

Итеративная функция для освобождения вашего списка:

void freeList(struct node* head)
{
   struct node* tmp;

   while (head != NULL)
    {
       tmp = head;
       head = head->next;
       free(tmp);
    }

}

Что делает эта функция:

  • проверьте, является ли head NULL, если да, список пуст, и мы просто возвращаем

  • Сохраните head в переменной tmp и сделайте head в следующем списке node в вашем списке (это делается в head = head->next

  • Теперь мы можем смело использовать переменную free(tmp), а head просто указывает на остальную часть списка, вернитесь к шагу 1

Ответ 2

Просто повторяя список:

struct node *n = head;
while(n){
   struct node *n1 = n;
   n = n->next;
   free(n1);
}

Ответ 3

Вы всегда можете сделать это рекурсивно так:

void freeList(struct node* currentNode)
{
    if(currentNode->next) freeList(currentNode->next);
    free(currentNode);
}

Ответ 4

Одна функция может выполнять задание,

void free_list(node *pHead)
{
    node *pNode = pHead, *pNext;

    while (NULL != pNode)
    {
        pNext = pNode->next;
        free(pNode);
        pNode = pNext;
    }

}