установить NULL на структурный адрес, переданный в качестве значения - PullRequest
0 голосов
/ 27 октября 2019

У меня есть список структуры, который я передаю функции, которая должна освободить содержимое и элемент списка (*l).

Я уже освобождаю содержимое с помощью функции del, но *lst делаетне получить освобождение.

typedef struct s_list
{
    void            *content;
    struct s_list   *next;
} t_list;

void lstdel_f(void *d)
{
    free(d);
}

void ft_lstdel(t_list *lst, void (*del)(void *))
{
    (*del)(lst->content);
    free(lst);
}

int main()
{
    //this line creates a new list
    t_list *l = ft_lstnew(ft_strdup("test"));

    ft_lstdel(l, &lstdel_f);
    printf("C=%s\n", l->content);

    if (l != NULL)
        puts("still here"); // shouldn't get here
    else
        puts("GOOD"); // should get here
}

Я не могу использовать двойной указатель в аргументах функции ft_lstdel.

Есть ли в любом случае установить NULL в списке, чтобы программа печатала"ХОРОШО"?

РЕДАКТИРОВАТЬ: я удалил актерский состав t_list **

Ответы [ 2 ]

1 голос
/ 27 октября 2019

Я не могу использовать двойной указатель в аргументах функции ft_lstdel.

В любом случае можно установить значение NULL в списке

Нет, нет. Не изнутри вашей ft_lstdel() функции. Если вы хотите изменить значение l изнутри ft_lstdel(), единственный способ - передать на него указатель. Кроме этого, вы могли бы установить его на NULL внутри main() после вызова ft_lstdel().

То, что вы в настоящее время делаете, неправильно, вы не можете просто наложить t_list * наt_list ** и ожидайте, что это сработает. Вы также делаете много ненужных операций с указателями. OP отредактировал вопрос.

Вы также не освобождаете весь список. В общем случае вам потребуется цикл, который сканирует все элементы next списка и освобождает весь список, в то время как вы освобождаете только один элемент.

Удаление ненужного, единственноеваша функция должна сделать следующее:

void ft_lstdel(t_list *lst, void (*del)(void *))
{
    del(lst->content);
    free(lst);
}

Обратите внимание, что это все еще не нормально, поскольку вы освобождаете только один элемент, когда вы должны освободить всех из них.

И если вы хотите установить l на NULL, то у вас есть для передачи указателя на него. Другого пути нет .

void ft_lstdel(t_list **lst_ptr, void (*del)(void *))
{
    t_list *lst = *lst_ptr;
    del(lst->content);
    free(lst);
    *lst_ptr = NULL;
}
0 голосов
/ 27 октября 2019

Нет, вы не можете. l передается по значению, поэтому ft_lstnew не может изменить копию вызывающей стороны. Без двойного указателя вам придется делать это вручную:

ft_lstdel(l, &lstdel_f);
l = NULL;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...