Может кто-нибудь объяснить, что с ним не так
Когда вы вызвали free
на узле, вы не можете получить доступ к head->next
. Вы должны освободить head->next
до head
.
и как правильно освободить связанный список из памяти?
Довольно элегантное решение - рекурсия. Рекурсия хороша для того, чтобы сделать код понятным, но если вы не знаете об опасностях, избегайте этого в рабочем коде. Я часто использую это для прототипирования. Вот пример.
void free_list(struct node *head)
{
if(head) {
// Before freeing the first element, free the rest
free_list(head->next)
// Now it's only one element left to free
free(head);
}
}
Это работает так. Допустим, у нас есть список: [e0, e1, e2, ..., en]
. Мы хотим освободить все элементы. Мы делаем это, сначала освобождая список [e1, e2, ..., en]
, а затем освобождая элемент e0
. Следующий шаг работает так же. Мы хотим освободить [e1, e2, ... en]
, поэтому мы начнем с вызова того же алгоритма из списка [e2, e3, ..., en]
, а когда это закончится, мы освободим e1
. Базовый случай - это когда мы получаем пустой список []
, в этом случае мы ничего не делаем.
Вы также можете делать это не рекурсивно. Это не так красиво, но часто более эффективно и устраняет риск переполнения стека. Вот как бы я написал это в рабочем коде.
void free_list(struct node *head)
{
struct node *tmp;
while(head) {
tmp = head;
head = head->next;
free(tmp);
}
}