删除链接列表功能

时间:2012-12-17 15:58:33

标签: c

这是我删除链表的功能:

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释放的东西不会删除它但只标记为可用,所以我不知道如何判断这是否正确。

4 个答案:

答案 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);

}