【问题标题】:What causes the segmentation fault in the doubly linked list code什么导致双向链表代码中的分段错误
【发布时间】:2018-12-05 13:56:12
【问题描述】:

当调用 printList 时,以下代码会导致分段错误。这是为什么呢?

失败的工作示例位于https://ide.geeksforgeeks.org/ZeqrQf9esb

#include <iostream>

struct Node {
    int data;
    Node * next;
    Node * prev;
};

void addNode(struct Node **head_ref,int pos,int data)
{
    struct Node*nn=new Node;
    int k=0;
    nn->data=data;
    if(*head_ref==nullptr)
        *head_ref=nn;
    else
    {
        struct Node*temp=*head_ref;

        while(k<pos)
        {
            temp=temp->next;
        }

        if(temp->next!=nullptr)
        {

            nn->prev=temp;
            nn->next=temp->next;
            temp->next=nn;
            nn->next->prev=nn;


        }
        else
        {
            nn->next=nullptr;
            nn->prev=temp;
            temp->next=nn;
        }
    }
}
 void printList(struct Node *Node)
    {
      struct Node *temp=Node;
      //goto end
      while(temp->next!=NULL)
      {
        temp=temp->next;
      }
      //goto start
      while(temp->prev!=NULL)
      {
       temp = temp->prev;
      }
      //now print
      while(temp!=NULL)
      {
          printf("%d ",temp->data);
          temp=temp->next;
      }

    }

int main()
{
    Node * head; 
    addNode(&head,0,10);
    addNode(&head,0,11);
    addNode(&head,0,12);


    std::cerr << head->data << std::endl;
    std::cerr << head->next->data << std::endl;
    std::cerr << head->next->next-> data << std::endl;  
      printList(head);
}

【问题讨论】:

  • 这段代码不能“运行” 请包括一个完整的例子,包括一个主要功能来展示你是如何使用它的。
  • 理想情况下,可以将代码粘贴到wandbox.org,它会运行并演示您的错误。
  • 我只包含了整个代码,包括主函数@bradgonesurfing
  • 你可以从简化代码开始,从几个简单的案例开始。例如,我为您完成了wandbox.org/permlink/N5MUzCDzEuGjNJoh,这不会导致分段错误。然后建立你的测试用例,直到你发现问题。
  • 非常感谢我成功运行代码,没有任何分段错误:) @bradgonesurfing

标签: c++ data-structures linked-list doubly-linked-list


【解决方案1】:

1) 不要在同一代码中混用 malloc 和 new。你会忘记哪些节点来自哪个分配器,如果你释放来自 new 的东西,或者删除来自 malloc 的东西,你就有一个严重的错误。

2) 在推进“k”次时……你忘记增加 k,所以永远不要停止推进,然后离开你的清单。这是崩溃的根源:

    while(k<pos)
    {
        temp=temp->next;
    }

可能还有更多,但我在看到 #2 后就不再寻找了。

【讨论】:

  • 我已将您建议的修复添加到 wandbox.org/permlink/VW6no2mZsW1TVLZZ,但仍有 segv
  • 你需要考虑如果你想插入位置 0 会发生什么(它之后会发生什么?你如何替换头部?)另外,如果你请求在最后插入,是临时空?如果 temp->next 为空,您可能想要停止此循环。然后判断是否是错误如果 k
【解决方案2】:

修复方法是将 next 和 prev 初始化为空。如果您不这样做,那么它们会采用随机值。重要的几行是

struct Node {
    int data;
    Node * next=nullptr;
    Node * prev=nullptr;
}; 

有关工作示例,请参阅 https://wandbox.org/permlink/qooehizoRifrvOVX。完整代码如下

#include <iostream>

struct Node {
    int data;
    Node * next=nullptr;
    Node * prev=nullptr;
};

void addNode(struct Node **head_ref,int pos,int data)
{
    struct Node*nn=new Node;
    int k=0;
    nn->data=data;
    if(*head_ref==nullptr)
        *head_ref=nn;
    else
    {
        struct Node*temp=*head_ref;

        while(k<pos)
        {
            temp=temp->next;
        }

        if(temp->next!=nullptr)
        {

            nn->prev=temp;
            nn->next=temp->next;
            temp->next=nn;
            nn->next->prev=nn;


        }
        else
        {
            nn->next=nullptr;
            nn->prev=temp;
            temp->next=nn;
        }
    }
}
 void printList(struct Node *Node)
    {
      struct Node *temp=Node;


      //goto end
      while(temp->next!=nullptr)
      {
        temp=temp->next;
      }


      //goto start
      while(temp->prev!=nullptr)
      {
       temp = temp->prev;
      }



      //now print
      while(temp!=nullptr)
      {
          printf("%d ",temp->data);
          temp=temp->next;
      }


    }

int main()
{
    Node * head; 
    addNode(&head,0,10);
    addNode(&head,0,11);
    addNode(&head,0,12);

    std::cerr << head->data << std::endl;
    std::cerr << head->next->data << std::endl;
    std::cerr << head->next->next-> data << std::endl;  

    printList(head);
}

【讨论】:

    猜你喜欢
    • 2011-07-07
    • 2021-09-14
    • 2012-08-14
    • 2017-08-18
    • 2011-01-10
    • 1970-01-01
    • 2021-11-25
    • 1970-01-01
    相关资源
    最近更新 更多