рекурсивная функция для освобождения памяти - PullRequest
2 голосов
/ 11 апреля 2020

Я пытаюсь написать рекурсивную функцию, которая освобождает весь связанный список. Я все еще довольно новичок в рекурсивных функциях, поэтому я не уверен, что делаю это правильно. Я запустил valgrind для своего кода и получил ошибку, но я не уверен, как ее интерпретировать.

==1156== 16 bytes in 1 blocks are indirectly lost in loss record 1 of 3
==1156==    at 0x4C2FB0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==1156==    by 0x422454: main (destroy.c:24)

Я считаю, что ошибка лежит где-то в моем коде. Любая помощь будет очень хорошей. Вот мой код:

#include <stdio.h>
#include <stdlib.h>

typedef struct node
{
    int number;
    struct node* next;
}
node;

void destroy(node* list);

int main (void)
{
    node* list = NULL;
    node* n = malloc(sizeof(node));
    if (n == NULL)
    {
        return 1;
    }
    n->number = 1;
    n->next = NULL;
    list = n;
    n = malloc(sizeof(node));
    if (n == NULL)
    {
        return 1;
    }
    n->number = 2;
    n->next = NULL;
    list->next = n;
    n = malloc(sizeof(node));
    if (n == NULL)
    {
        return 1;
    }
    n->number = 3;
    n->next = NULL;
    list->next->next = n;

    destroy(list);
}

void destroy(node* list)
{
    if(list->next == NULL)
    {
        free(list);
    }
    else
    {
        return destroy(list->next);
    }
}

1 Ответ

4 голосов
/ 11 апреля 2020

Вы освобождаете только один узел, который находится в конце списка. Потому что "узлы" не освобождаются, когда рекурсия раскручивается.

Вы бы переписали это следующим образом:

void destroy(node* list)
{
    if (list == NULL) return;
    destroy(list->next);
    free(list);
}

Но IMO, рекурсия здесь не нужна. Простой l oop может быть лучшим выбором:

void destroy(node* list)
{
    node* temp;

    while (list != NULL) {
        temp = list;
        list = list->next;
        free(temp);
    }
}

Подумайте о тысячах узлов в списке. Почему вы хотите «сохранить» узлы в стеке вызовов без уважительной причины? Это неэффективно и опасно (стек вызовов может переполниться).

...