Код, который вы разместили, должен работать для односвязных или двусвязных списков, но делает некоторые допущения:
- что очистка узла не производится перед его освобождением;это часто неверное предположение.
- что конец списка помечен нулевым указателем (т. е. член
Next
последнего узла равен NULL
)
Относительно первого предположения: Поскольку у вас есть динамически распределенные данные в ваших узлах, и предполагается, что у вас нет другого указателя на них где-то еще, который вы будете использовать для очистки их позже, вам нужно будет освободить этоданные, прежде чем освободить каждый узел.В Си это не сделано для вас;общее правило заключается в том, что если вы должны были распределить его самостоятельно, вы должны освободить его и сами.Разумный способ справиться с этим - написать функцию для очистки и освобождения узла и вызвать ее вместо простого вызова free()
;Ваша функция очистки по-прежнему освобождает узел, но сначала освобождает данные узла.
Что касается второго предположения: Довольно распространенная практика - указывать указатель Next
последнего узла наNULL
для обозначения конца, поскольку с его помощью легко определить, когда вы прошли весь список.Для двусвязного списка то же самое относится к указателю Prev
первого узла *1022*.Однако, если это круговой список, последний узел просто указывает на первый узел - и это нарушит код, который вы опубликовали.В этой ситуации вы должны начать с узла head->Next
вместо head
и проверить, не является ли current
head
, а не NULL
.Затем разберитесь с head
в конце, так как вы сначала его пропустили.
И еще одна вещь: Убедитесь, что после того, как вы закончили освобождение своего списка, вы не покидаете его.head
указывает на недопустимый (уже освобожденный) узел, а затем снова пытается получить доступ к списку ...