C: Как освободить узлы в связанном списке? - PullRequest
21 голосов
/ 21 июня 2011

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

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. Не следует звонить бесплатно (h) удалить h. Если так, то почему доступны h-> next-> data, если h свободен? Конечно, «второй» узел не освобождается. Но поскольку голова удалена, она должна иметь возможность ссылаться на следующий элемент. В чем здесь ошибка?

Ответы [ 4 ]

50 голосов
/ 21 июня 2011

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

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

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

}

Функция выполняет следующее:

  1. проверка, если head равно NULL, еслида, список пуст, и мы просто возвращаем

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

  3. Теперь мы можем безопасно free(tmp) переменную, а head просто указывает на остальную часть списка, вернуться к шагу 1
3 голосов
/ 21 июня 2011

Просто перебирая список:

struct node *n = head;
while(n){
   struct node *n1 = n;
   n = n->next;
   free(n1);
}
1 голос
/ 21 июня 2011

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

void freeList(struct node* currentNode)
{
    if(currentNode->next) freeList(currentNode->next);
    free(currentNode);
}
0 голосов
/ 29 января 2018

Одна функция может сделать работу,

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

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

}
...