Обновление: Это было написано до того, как был предоставлен вызывающий объект free. Теперь, когда я вижу это, я бы сказал, что да, вы не можете вызвать free
для стекового адреса. Однако мой оригинальный ответ сохранился ниже, о том, как лучше сделать удаление списка ...
Я не вижу внезапной ошибки free
, но .... кажется, что этот подход будет работать, только если переданный node
является первым узлом. Если это какой-то другой узел, кроме первого, вам понадобится указатель на предыдущий, чтобы вы могли установить prev->next = node->next
.
На самом деле, думая об этом больше ... Если все, что вы делаете - это берете узел и делаете его последним, зачем вам нужно free
что-нибудь? Похоже, этот код освобождает весь список, начиная с temp
. Если это ваше намерение, я рекомендую что-то более похожее на это:
void free_all_at_node(struct list **list, struct list *node_to_free)
{
struct list *n = *list, *prev = NULL;
// Search for node_to_free, updating prev to indicate the last node we saw.
//
while (n && n != node_to_free)
{
prev = n;
n = n->next;
}
// Check to see if we found it...
//
if (n == node_to_free)
{
// Do we have a previous node?
//
if (prev)
{
// Yes, update next pointer...
//
prev->next = NULL;
}
else
{
// This is the start of the list. Update the head...
//
*list = NULL;
}
// Now free stuff...
//
while (n)
{
struct list *next = n->next;
free(n);
n = next;
}
}
}
Предполагается, что вы хотите, чтобы node_to_free
был первым освобожденным узлом, и, следовательно, мы ищем его по началу списка. Другая альтернатива заключается в том, чтобы вызывающая сторона указывала узел до первого свободного узла. (Похоже, ваш код на самом деле пытается это сделать ...) Я мог бы предпочесть сделать это так:
void free_after_node(struct list *n)
{
// If the node is NULL or has no next node, there is nothing to do.
//
if (n && n->next)
{
// Start at the node after the first, since we want to keep the first
// one around.
//
n = n->next;
// Now free...
//
while (n)
{
struct list *next = n->next;
free(n);
n = next;
}
}
}