简体   繁体   English

C 双循环链表删除

[英]C Doubly Circular Linked List Deletion

I'm having a problem deleting from a circular doubly linked list.我在从循环双向链表中删除时遇到问题。 I have tried various different methods mentioned here, but they all cause some sort of error.我尝试了这里提到的各种不同的方法,但它们都会导致某种错误。 Here, I'm getting an error saying "double free detected in tcache 2"在这里,我收到一条错误消息“在 tcache 2 中检测到双重空闲”

void delete_list(Node *node)
{
        Node *pt;
        while(node != NULL){
                pt = node;
                node = node->next;
                free(pt);
        }
}

I'm having a problem deleting from a circular doubly linked list我在从循环双向链表中删除时遇到问题

A circular doubly linked list does not have a node with the data member next that is equal to NULL .循环双向链表没有数据成员next等于NULL的节点。 The tail node in its data member next has the address of the head node.其数据成员中的tail节点next具有head节点的地址。

So if your list is not empty then this function因此,如果您的列表不为空,那么此 function

void delete_list(Node *node)
{
        Node *pt;
        while(node != NULL){
                pt = node;
                node = node->next;
                free(pt);
        }
}

invokes undefined behavior after it moves from the tail node to the head node that it tries to free twice.在它从tail节点移动到尝试释放两次的head节点后调用未定义的行为。

The function can look for example the following way (without testing) function可以看下面的方式(未经测试)

void delete_list( Node **head )
{
    if ( *head )
    {
        Node *current = ( *head )->next;
     
        while ( current != *head )
        {
            Mode *tmp = current;
            current = current->next;
            free( tmp );
        }

        free( *head );
        *head = NULL;
    }
}

If in main you have a declaration like如果主要你有一个声明

Node *head = NULL;
//...

then the function can be called like那么 function 可以这样称呼

delete_list( &head );

Pay attention to that the function does not deal with the pointer to the tail node if it is declared separately apart from the pointer to the head node.请注意,function 如果与指向头节点的指针分开声明,则不处理指向尾节点的指针。

In this case you need to introduce one more structure as for example在这种情况下,您需要引入另外一种结构,例如

struct CircularList
{
    Node *head;
    Node *tail;
};

that indeed defines a list.这确实定义了一个列表。 And call the (modified) function for an object of this type.并为这种类型的 object 调用(修改的)function。

free'ing a node in a doubly linked list does NOT remove that node from the list.释放双向链表中的节点不会从列表中删除该节点。

The code must correct the 'next' field of the prior node in the list and correct the 'prev' field of next node in the list so those fields skip the node to be deleted, Then the node to be deleted can be passed to free()代码必须更正列表中前一个节点的'next'字段并更正列表中下一个节点的'prev'字段,以便这些字段跳过要删除的节点,然后可以将要删除的节点传递给free()

void delete_list(Node **head){
        Node *current, *garbage;

        if (*head==NULL) return; else current=(*head)->next;

        while(current != *head){
                garbage=current;
                current = current->next;
                free(garbage);
        }

        free(current);
        *head=NULL;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM