这是我删除链表的功能:
void deleteList( NODE* head )
{
NODE* temp1;
NODE* tempNext;
temp1 = head;
tempNext = NULL;
while( temp1 != NULL )
{
tempNext = temp1->next;
free(temp1);
temp1 = tempNext;
}
}
所以temp1首先指向头指针指向的位置。如果不是NULL
,则tempNext
将设置为指向列表的下一个元素。然后第一个元素(temp1
)被释放,temp1
被重新分配以指向tempNext
指向的位置并处理重复。
这是删除整个列表的正确方法吗?
我问这个是因为在使用此功能后打印列表时,它仍会打印列表。 IIRC释放的东西不会删除它但只标记为可用,所以我不知道如何判断这是否正确。
答案 0 :(得分:7)
您的代码看起来是正确的。
你也是正确的,释放列表的元素不会立即改变他们指向的内存。它只是将内存返回给堆管理器,它可能会在将来重新分配它。
如果要确保客户端代码不会继续使用已释放的列表,可以将deleteList
更改为NULL NODE
指针:
void deleteList( NODE** head )
{
NODE* temp1 = *head;
/* your code as before */
*head = NULL;
}
答案 1 :(得分:1)
它仍会打印列表,因为在调用此函数后,您可能没有将head
指针设置为NULL
。
答案 2 :(得分:1)
I ask this because when I print the list after using this function, it still prints the list.
free
指针与指针无效之间存在差异。如果您free
整个链接列表和头部,则表示您不再“拥有”head
和所有next
指针指向的位置的内存。因此,你无法想象那里会有什么价值,或者记忆是有效的。
然而,如果你在释放链表后没有碰到任何东西,那么你仍然能够遍历它并打印出值,这样的可能性非常大。
struct node{
int i;
struct node * next;
};
...
struct node * head = NULL;
head = malloc(sizeof(struct node));
head->i = 5;
head->next = NULL;
free(head);
printf("%d\n", head->i); // The odds are pretty good you'll see "5" here
您应该始终释放指针,然后直接将其设置为NULL,因为在上面的代码中,注释为true。在调用head
之后,对{{>} free()
如何反应/包含做出任何假设也是危险的。
答案 3 :(得分:0)
这是一个非常古老的问题,但也许它可以帮助某人对该主题进行搜索。
这是我最近写的完全删除单链表的内容。我看到很多人因涉及大型列表的递归算法而感到胃灼热,因为他们担心耗尽堆栈空间。所以这是一个迭代版本。
只需通过" head"指针和功能负责其余...
struct Node {
int i;
struct Node *next;
};
void DeleteList(struct Node *Head) {
struct Node *p_ptr;
p_ptr = Head;
while (p_ptr->next != NULL) {
p_ptr = p_ptr->next;
Head->next = p_ptr->next;
free(p_ptr);
p_ptr = Head;
}
free(p_ptr);
}