【问题标题】:Deleting a node from a doubly linked list从双向链表中删除节点
【发布时间】:2015-12-15 03:29:11
【问题描述】:

这是我当前的代码,我搞砸了,所以我如何处理第一项或唯一一项是错误的,这是该函数的前 2 部分。出于某种原因,如果我只是尝试设置 node=node->next_.. 我会遇到内存错误。我认为这将是最简单的方法,但是当我把它放回程序时,我开始遇到内存访问问题。只要我不操纵头地址,所有其他部分都可以正常工作。

void removeNode(struct student_record_node* node)
{
    struct student_record_node *temp=NULL;
    temp=node;
    if(node->next_==NULL&&node->prev_==NULL)
    {
        node=node->next_
        free(node->prev_);
    }
    else if(node->prev_==NULL&& node->next_!=NULL)
    {
        node=node->next_
        free(node->prev_);
    }

    else if(node->next_!=NULL && node->prev_!=NULL)
    {
        node->prev_->next_ = node->next_;
        node->next_->prev_ = node->prev_;
        student_record_node_deallocate(node);
    }
    else if(node->prev_!=NULL&& node->next_==NULL)
    {
        node->prev_->next_=node->next_;
        student_record_node_deallocate(node);
    }
}

【问题讨论】:

  • 请发帖Minimal Complete and Verifiable Example。根本原因可能在也可能不在此代码中或仅在此代码中。
  • 在双向链表中,永远不应该有指向下一个或上一个的空节点指针。如果只有 1 个节点,则它指向自身。 node->next->prev = node->prev; node->prev->next = node->next; free(node);
  • @WalterM 双向链表不必包含任何空指针。在双向链表中,头节点的 prev 为 NULL,最后一个节点的 next 为 NULL。您所说的内容存在于循环链接列表中。
  • 如果你想改变头指针的节点,我认为你需要传递headptr的地址并用双指针捕获它

标签: c doubly-linked-list


【解决方案1】:

有几个错误:

  1. 节点可能是头,所以应该返回struct student_record_node*,而不是void

  2. 节点可能是NULL

  3. 如果node->prev_NULL,请确保释放已删除的节点。

【讨论】:

  • free 带有NULL 参数不会导致重大问题。来自free man page:“如果ptr为NULL,则不执行任何操作。”
【解决方案2】:

由于您没有提供您的链表是什么样的,我将假设我的代码示例是一个包含指向链表(第一个元素)的head 的指针的结构。由your_list引用。

问题在于代码中的前两个if-blocks;

  • 第一个ifif(!node->next_ && !node->prev_)

    这意味着您正在删除列表的头元素。在这种情况下,您必须将头显式设置为NULL,而不是将指向要删除的节点的指针设置为NULL(通过将其设置为其前身,即NULL)。此外,您通过释放前一个节点来释放NULL-Pointer。这本身没问题,但你想删除node,而不是它的前身。

  • 第二个if:if(!node->prev_ && node->next_):

    这意味着你正在删除头部,但删除节点后列表不会为空。在这种情况下,您必须将列表的头设置为指向新的头,这将是node->next_ 指向的节点。另外,free() 也有类似的问题。

解决这两点,您的代码应该按照以下方式做一些事情:

void removeNode(struct student_record_node *node){
    if(!node->next_ && !node->prev_){
        your_list->head = NULL; // Remove head - List is now empty.
        student_record_node_deallocate(node);
        node = NULL; // Set freed pointer to NULL, for safety.
    }
    else if(!node->prev_ && node->next_){
        your_list->head = node->next_; // Set the head to the new head.
        student_record_node_deallocate(node);
        node = NULL; // Set freed pointer to NULL, for safety.
    }
    else if(node->next_ && node->prev_){
        node->prev_->next_ = node->next_;
        node->next_->prev_ = node->prev_;
        student_record_node_deallocate(node);
        node = NULL; // Set freed pointer to NULL, for safety.
    }
    else if(node->prev_ && !node->next_){
        node->prev_->next_ = NULL;
        student_record_node_dealocate(node);
        node = NULL; // Set freed pointer to NULL, for safety.
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-02-14
    • 2013-09-01
    • 2016-10-09
    相关资源
    最近更新 更多