Segmentation fault C ++

1
#include <stdio.h>
#include <iostream>

using namespace std;

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

nodeDouble* head;
nodeDouble* tail;

void addNode(int number){
  if(head == NULL){
    head = (nodeDouble*)malloc(sizeof(struct nodeDouble));
    head->data = number;
    head->next = NULL;
    head->prev = NULL;
    tail = head;
  }else{
    tail->next = (nodeDouble*)malloc(sizeof(struct nodeDouble));
    tail->next->data = number;
    tail->next->prev = tail;
    head->next->next = NULL;
    tail = tail->next;
  }
}

void printList(nodeDouble* headList){

  while(headList != NULL){
    cout << headList->data << "\n";
    headList = headList->next;
  }
  headList = NULL;
}

int main(){
  for (int i = 0; i < 15; i++) {
    addNode(i);

  }
  printList(head);
  return 0;
}
    
asked by Oliver Brandon 13.10.2018 в 20:56
source

3 answers

3

Look at this apparently harmless line (found in addNode ):

head->next->next = NULL;

This line is breaking your linked list. By the time you add three elements, this line will cut the list. That is, your list will look like this:

head                    tail
node -> node -> null    node -> null

When you expect it to look like this:

head            tail
node -> node -> node -> null

And of course, if you iterate from head to tail without checking pointers you end up finding that third node that is null and that's where the problems start.

Since you are in C ++ I suggest, as you do in the other answer, that you stop using malloc and you happen to use new . Along with this change, define an appropriate constructor and the problem will be solved only :

struct nodeDouble{
  int data;
  nodeDouble* next;
  nodeDouble* prev;

  nodeDouble(int value)
    : data(value),
      next(nullptr),
      prev(nullptr)
  { }
};

nodeDouble* head = nullptr;
nodeDouble* tail = nullptr;

void addNode(int number){
  nodeDouble * node = new nodeDouble(number);

  if(head == nullptr){
    head = node;
  }else{
    tail->next = node;
    node->prev = tail;
  }

  tail = node;
}

What happens now is that new invokes, implicitly, the constructor that we declared in the class. This constructor initializes the pointers next and prev a nullptr (natural substitute of NULL in the C ++ 11 standard). In addition also initializes data from a value that we provide.

Later we will only update those pointers that we need and that's it, the list will be correctly linked.

We could also create a little more complete builder:

struct nodeDouble{
  int data;
  nodeDouble* next;
  nodeDouble* prev;

  nodeDouble(int value, nodeDouble* previous)
    : data(value),
      next(nullptr),
      prev(previous)
  {
    if( nullptr != previous )
      previous->next = this;
  }
};

nodeDouble* head = nullptr;
nodeDouble* tail = nullptr;

void addNode(int number){
  nodeDouble * node = new nodeDouble(number,tail);

  if(head == nullptr)
    head = node;

  tail = node;
}

Now the constructor also receives a pointer to the previous node. If this pointer is null, it does nothing, but if it is not, it adds to the end of the list, so it would only be necessary to update tail .

    
answered by 13.10.2018 в 22:22
1

Nodes are not Lists.

This is a recurring error in StackOverflow in Spanish that generates a lot of confusion.

In the code you have provided you are passing variables of type nodeDouble with list name and that is as wrong as saying that a step is a ladder, honestly Do you think the same?:

The nomenclature is important.

In addition to the incorrect nomenclature that confuses nodes with lists, your node is called nodeDouble but the data contained is int Are you sure you're doing what you want?

Your question is about C ++.

The header <stdio.h> is from not from

answered by 15.10.2018 в 11:08
0

Try to initialize head and tail to null:

nodeDouble* head = NULL;
nodeDouble* tail = NULL;

Although in C ++ you should avoid using pointers (or, if you have to use them, try using smart pointers, like std :: unique_ptr). If you are going to use pointers, try using nullptr (instead of NULL).

On the other hand, try to avoid malloc (in the vast majority of cases, use malloc is undefined behavior in C ++), use new:

head = new nodeDouble();
    
answered by 13.10.2018 в 21:26