Что вызывает ошибку сегментации в коде двусвязного списка - PullRequest
0 голосов
/ 05 декабря 2018

Когда вызывается 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);
}

Ответы [ 2 ]

0 голосов
/ 05 декабря 2018

Исправление заключается в инициализации следующего и 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);
}
0 голосов
/ 05 декабря 2018

1) не смешивайте malloc и new в одном и том же коде.Вы потеряете информацию о том, какие узлы пришли с какого распределителя, и если вы освободите что-то из нового или удалите что-то из malloc, у вас будет серьезная ошибка.

2) при увеличении "k" раз... вы забываете увеличивать k, поэтому никогда не прекращайте продвижение и уходите от своего списка.Это источник сбоев:

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

Могут быть и другие, но я перестал смотреть после просмотра # 2.

...