简体   繁体   中英

What causes the segmentation fault in the doubly linked list code

When printList is called the following code causes a segmentation fault. Why is this?

A working example of the failure is at 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);
}

1) don't mix malloc and new in the same code. You'll lose track of which nodes came from which allocator and if you free something that came from new, or delete something that came from malloc, you have a serious bug.

2) while advancing "k" times... you forget to increment k so never stop advancing, and walk off your list. That's a source of crashes:

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

There may be more, but I stopped looking after seeing #2.

The fix is to initialize next and prev to be null. If you don't do this then they take random values. The important lines are

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

See https://wandbox.org/permlink/qooehizoRifrvOVX for a working example. Full code below

#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);
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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