Getting Segmentation fault while traversing linked list - c++

I've simple C++ program to traverse a linked list.
It runs perfectly in ideone .
When I run this in my mac terminal it throws segmentation fault.
When I uncomment //printf("Node"); line from traverse function it runs perfectly. I'm not able to understand this behavior.
#include <iostream>
#include <bits/stdc++.h>
using namespace std;
typedef struct node {
int data;
struct node *next;
} Node;
void traverseLinkedList(Node *start) {
while(start) {
//printf("Node");
cout << start->data << "->";
start = start->next;
}
cout << "NULL" << endl;
}
int main() {
Node *start = (Node*) malloc(sizeof(Node));
Node *a = (Node*) malloc(sizeof(Node));
Node *b = (Node*) malloc(sizeof(Node));
start->data = 0;
a->data = 1;
b->data = 2;
start->next = a;
a->next = b;
traverseLinkedList(start);
traverseLinkedList(a);
traverseLinkedList(b);
return 0;
}

You forgot this statement
b->next = nullptr;
Otherwise the program has undefined behavior due to the condition in this while statement in the function traverseLinkedList
while(start)
Take into account that in C++ you should use the operator new instead of the C function malloc.
For example
Node *b = new Node { 3, nullptr };
Node *a = new Node { 2, b };
Node *start = new Node { 1, a };
And you should free the allocated memory before exiting the program.

Related

My program stops working from a while loop when using dynamic allocated lists

I've been studying about dynamic allocated lists (the stuff we are discussing right now in class is pretty outdated tbh) and I can't seem to access the next node in a list. (I've just began learning this topic)
The problem is that the while loop that I'm using for going through the list never stops. I'm definitely missing something and I don't understand what.
struct node {
int info;
node* next;
};
int main()
{
node *p, *prim=NULL;
p = prim;
node* t;
t = new node;
p->next = t;
while (p != NULL)
{
cout << "test";
p = p -> next;
}
return 0;
}
Here is the code.
Why does my program not output anything and also tells me "it exited with code -1073741819" instead of 0?
Thanks.
////edit: I forgot to tell you that I've tried this way too
struct node {
int info;
node* next;
};
int main()
{
node *p, *prim=NULL;
p = prim;
node* t;
t = new node;
prim->next = t;
while (p != NULL)
{
cout << "test";
p = p -> next;
}
return 0;
}
Let's analyze your code:
node *p, *prim=NULL; // prim is NULL, p not yet initnialized
p = prim; // p now equal to NULL as well
node* t;
t = new node; // t is allocated
p->next = t; // NULL->next = t
So you're crashing on a null pointer when you try to dereference p->next for assignment.
It looks like you're trying to setup a basic linked list and loop through it. Your loop looks good, but you forgot the part where you actually setup the list!
That could look like:
struct node {
int info;
node* next;
//Add a quick constructor to make creating new nodes easy
node(int i) : info(i), next(nullptr) { }
};
int main()
{
//Start out with 3 itmes
// This list will look like:
// head -> 5 -> 3 -> 1
node *head = new node(5);
head->next = new node(3);
head->next->next = new node(1);
//Loop through the list and print each value
for(node *p = head; p; p = p->next) {
std::cout << p->info << std::endl;
}
//Don't forget to delete the memory you allocated to prevent a leak!
for(node *p = head; p;) {
node *temp = p->next;
delete p;
p = temp;
}
return 0;
}
See it run: https://ideone.com/WngD3b

Error "Abort signal from abort(3) (sigabrt) " for linked list in C++

The following code is for a basic circular linked list, but when one inputs a large value for n(e.g 8 digits) it throws the "abort signal from abort(3) (sigabrt)" error. I'm not sure what it means and would love some guidance about fixing this with regard to my code.
Thank you!
#include<bits/stdc++.h>
using namespace std;
//First I created a structure for a node in a circular linked list
struct Node
{
int data;
struct Node *next;
};
// function to create a new node
Node *newNode(int data)
{
Node *temporary = new Node;
temporary->next = temporary;
temporary->data = data;
return temporary;
}
// This function finds the last man standing in
//the game of elimination
void gameOfElimination(int m, int n)
{
//first I created a circular linked list of the size which the user inputted
Node *head = newNode(1);
Node *prev = head;
//this loop links the previous node to the next node, and so on.
for (int index = 2; index <= n; index++)
{
prev->next = newNode(index);
prev = prev->next;
}
prev->next = head; //This connects the last and first nodes in our linked list together.
//when only one node is left, which is our answer:
Node *ptr1 = head, *ptr2 = head;
while (ptr1->next != ptr1)
{
int count = 1;
while (count != m)
{
ptr2 = ptr1;
ptr1 = ptr1->next;
count++;
}
/* Remove the m-th node */
ptr2->next = ptr1->next;
ptr1 = ptr2->next;
}
printf ("%d\n ",
ptr1->data);
}
//main program which takes in values and calls the function:
int main()
{
int n, p;
cin>>n>>p;
int m=p+1;
gameOfElimination(m, n);
return 0;
}
SIGABRT is generally issued when there are memory issues (heap corruption being quite common). In your code, I see only the new() operator being called, but you aren't deleting any unused nodes from your linked list! Seems like you're exhausting the memory allocated to your process.
You might be running out of memory. Check your ram usage during the execution of your program, that might lead to something.
enter code here
#include<bits/stdc++.h>
using namespace std;
class Node{
public:
int data;
Node *next;
};
void traverse(Node *head)
{
while (head != NULL)
{
/* code */
cout<<head->data<<"->";
head = head->next;
}
cout<<"NULL"
}
int main()
{
Node *head = new Node();
Node *second = new Node();;
Node *third = new Node();;
Node *fourth = new Node();;
head->data = 5;
head->next = second;
//cout<<head->data;
second->data=10;
second->next=third;
third->data = 15;
third->next = fourth;
fourth->data = 20;
fourth->next= NULL;
traverse(head);
return 0;
}```

inconsistent segmentation faults during runtime

I'm currently taking a jab at Project Euler #9 and am encountering segmentation faults. These segfaults only occur with every 3rd-4th time I run the program. Could someone explain why this might be the case and more importantly, why it doesn't segfault (or work) every time instead?
I've pinpointed the segfault to the beginning of the 2nd while loop but still can't determine the root cause.
#include <iostream>
#include "LinkedList.h"
using namespace std;
int main(){
int square, sum, answer = -1;
int start = 1;
LinkedList tripletChoices;
while (square<=1000){
//create new node
node * factor = new node;
factor->root = start;
square = start*start;
factor->square = square;
//insert into list
if (square<=1000) tripletChoices.insertNode(factor);
start++;
}
node * a_factor = tripletChoices.head;
/** segfaults just after this ***********************/
cout<<"before segfault" << endl;
while(a_factor->next!=NULL){
cout<<"after segfault" << endl;
node * b_factor = a_factor->next;
while(b_factor->next!=NULL){
sum = a_factor->square + b_factor->square;
cout<<"A: " << a_factor->square << " B: " << b_factor->square<< " sum:" << sum <<endl;
node * c_factor = tripletChoices.head;
while(c_factor->next!=NULL){
if (sum == c_factor->square){
if ((a_factor->root + b_factor->root + c_factor->root)==1000){
answer = a_factor->root * b_factor->root * c_factor->root;
break;
}
}
c_factor = c_factor->next;
}
b_factor = b_factor->next;
}
a_factor = a_factor->next;
}
cout<<"Answer: " << answer << endl;
}
the rest of my code (if relevant):
LinkedList.h
#ifndef LinkedList_h
#define LinkedList_h
struct node{
int root;
int square;
node *next;
};
class LinkedList{
public:
node * head;
int listLength;
//default constructor creates head node
LinkedList();
//setter method
bool insertNode(node * newNode);
//destructor de-allocates memory used by the list
~LinkedList();
};
#endif
LinkedList.cpp
#include "LinkedList.h"
#include <iostream>
//Default Constructor - initilizes list with head node
LinkedList::LinkedList(){
head = NULL;
listLength = 0;
}
// setter method for inserting a new node
// inserts new node at the head of the list
bool LinkedList::insertNode(node * newNode){
newNode->next = head;
head = newNode;
listLength++;
return true;
}
//Destructor de-allocates memory used by list
LinkedList::~LinkedList(){
node * p = head;
node * q = head;
while(q){
p = q;
q = p->next;
if (q) delete p;
}
}
Undefined behavior because of accessing uninitialized local variable
You are accessing uninitialized variable square before entering while loop, so it may or may not enter the while loop. So tripletChoices.head may or may not be non-null as you can't be sure if there would have happened any insertion or not!
Thus, dereferencing the null valued a_factor in while(a_factor->next!=NULL) would cause the SegFault.

Create and Display Linked List

I am a beginner in C++ and need help in many things. Well, for the starters, I have been working on Linked List and not really getting why my header(the first pointer which points towards first node) keep on rotating. I am just pointing it towards first node plus my display node is just displaying last node, why is it so?. Please tell me where I am wrong. Thank you in advance
#include <iostream>
#include <conio.h>
using namespace std;
struct Node
{
int data;
Node *link;
};
Node* create_Node()
{
int no_of_nodes;
Node *header = new Node;
Node *ptr = new Node;
header = ptr;
cout << "Enter no of nodes:";
cin >> no_of_nodes;
cout << "Enter data:";
for(int n = 0; n < no_of_nodes; n++)
{
cin >> ptr->data;
Node *temp = new Node;
ptr->link = temp;
temp = ptr;
}
ptr->link = NULL;
return ptr;
}
void display_link_list(Node * list)
{
Node *temp = new Node;
temp = list;
while(temp != NULL)
{
if(temp->link != NULL)
{
cout << "List:" << list->data << endl;
temp = temp->link;
}
}
}
int main()
{
Node *n = new Node;
n = create_Node();
display_link_list(n);
getch();
return 0;
}
Welcome to C++. My advice here is to break the Linked list into two. First the Nodes and then a List struct.
struct Node
{
int data;
Node *next;
Node(int data) : data(data), next(NULL) {}
};
struct List {
Node* tail;
Node* head;
List() : head(NULL), tail(NULL) {}
void insert(int data) {
if(head==NULL) {
head = new Node(data);
tail = head;
} else {
tail->next = new Node(data);
tail = tail->next;
}
}
};
Now you can insert one element into the list at a time and use head to print the list from beginning to end.
Something basic that you need to understand:
When you do Node* p = new Node, you are setting variable p to point to the start address of a piece of memory, the size of which being equal to sizeof(Node).
Now, when you then do p = something else (which often appears in your code), you are essentially overriding the previous value of p with some other value. It is like doing:
int i = 5;
i = 6;
So your code does not do what you're expecting to begin with.
In addition to that, what's bad about overriding the first value with a second value in this case, is the fact that the first value is the address of a dynamically-allocated piece of memory, that you will need to delete at a later point in your program. And once you've used p to store a different value, you no longer "remember" that address, hence you cannot delete that piece of memory.
So you should start by fixing this problem in each of the following places:
Node *header = new Node; // Variable 'header' is assigned
header = ptr; // Variable 'header' is reassigned
Node *temp = new Node; // Variable 'temp' is assigned
temp = list; // Variable 'temp' is reassigned
Node *n = new Node; // Variable 'n' is assigned
n = create_Node(); // Variable 'n' is reassigned

Attempting to create a pointer to previous object inside object

I'm attempting to create a vector of pointers to Nodes, where each node stores a pointer to the previous Node in the list.
I made a small test program to see if I could access a variable gscore in the previous object to the one I call.
#include <iostream>
#include <vector>
using namespace std;
struct Node
{
Node(int gscore1)
{
gscore = gscore1;
}
Node *previous;
int gscore;
};
int main()
{
std::vector<Node*> nodeVec;
Node *tempnode;
tempnode = new Node(10);
Node *tempnode2;
tempnode = new Node(11);
nodeVec.push_back(tempnode);
nodeVec.push_back(tempnode2);
nodeVec[1]->previous = tempnode;
cout << nodeVec[1]->previous->gscore << endl;
return 0;
}
However this results in a crash. What is the correct way to do this?
You never initialize tempnode2. You initialize tempnode twice.
int main()
{
std::vector<Node*> nodeVec;
Node *tempnode;
tempnode = new Node(10);
Node *tempnode2;
tempnode2 = new Node(11); // <<---- HERE
nodeVec.push_back(tempnode);
nodeVec.push_back(tempnode2);
nodeVec[1]->previous = tempnode;
cout << nodeVec[1]->previous->gscore << endl;
return 0;
}
Looks like a typing error. The third line in main() should be tempnode2 not tempnode.