CPP- I am getting Segmentation fault (core dumped)? - c++

I am trying to implement a singly linked list.. I am executing the code on terminal and i get the Segmentation fault (core dumped). I dont understand why is it happening? I read the other answers for the same and unfortunately none of them helped..
Any help will be appreciated..Please explain where did it went wrong? Thanks!
//singly linked list
#include<iostream>
using namespace std;
class node
{
int data;
node *next;
public:
node() //constructor
{
data=0;
next=NULL;
}
void setdata(int x)
{
data=x;
}
void setnext(node *x)
{
next=x;
}
int getdata()
{
return data;
}
node* getnext()
{
return next;
}
};
class list
{
node *head;
public:
list() // constructor
{
head=NULL;
}
void firstnode(int x)
{
node *temp;
temp=new node;
temp->setdata(x);
temp->setnext(head);
head=temp;
}
void insertbeg(int x)
{
node *temp1;
temp1=new node; //Allocate memory to temp1
temp1->setdata(x); // set data in new node to be inserted
temp1->setnext(head); // new node points to previous first node
head=temp1; // head now points to temp1
}
void insertbet(int x,int y)
{
node *temp1;
node *temp2;
temp1=new node; // Allocate memory to temp1
temp2=new node; // Allocate memory to temp2
temp1=head; // point temp1 to head so both of them point to first node
for(int i=0;i<y;i++) // To reach the desired node where data is to be inserted
{
temp1->getnext(); // point to next of node pointed by temp
temp1=temp1->getnext(); // temp1 now contains address of node pointed by next
}
temp2->setdata(x);
temp2->setnext(temp1->getnext()); // insert new node in list
temp1->setnext(temp2); // points the y-1 node to new node
}
void insertend(int x)
{
node *temp1;
node *temp2;
temp1=new node;
temp2=new node;
temp1=head;
while(temp1!=0)
{
temp1=temp1->getnext();
}
temp2->setdata(x);
temp1->setnext(temp2);
temp2->setnext(NULL);
}
void print()
{
node *temp1;
temp1=new node;
temp1=head;
while(temp1!=0)
{
cout<<temp1->getdata()<<endl;;
temp1=temp1->getnext();
}
}
};
int main()
{
list l;
l.firstnode(4);
l.insertbeg(3);
l.insertbeg(4);
l.insertbeg(6);
l.insertend(45);
l.insertend(9);
l.insertbet(2,46);
l.print();
return 0;
}
edit:Sorry guys i am new to coding, i am trying to debug with little progress. I already read the question,the answer is too broad, i need something specific to solve the error.

That's why there are debug tools like gdb (just google for it ;) ).
This is the backtrace:
#0 0x00000000004009ba in node::setnext (this=0x0, x=0x614cc0) at a.cpp:25
#1 0x0000000000400c18 in list::insertend (this=0x7fffffffdf10, x=45) at a.cpp:109
#2 0x00000000004008df in main () at a.cpp:137
that means in line 137 there is a function call (l.insertend(45)), then in line 109, there is the next function call (temp1->setnext(temp2)) and the segfault occurs on line 25 (next = x). This is because the node is not initialised (temp1 is 0 in line 109).
Your while-loop is the problem, if you change is to something like this:
while (temp1->getnext() != 0)
temp1 = temp1->getnext();
This will solve your first issue, but you will get another segfault ;)
Try to solve it on your own with the tools provided. If you still need help, please leave a comment and I will post the answer.

Related

pointer to pointer in linkedlist cannot preserve the pointer after every call from the main function. Why?

#include<iostream>
#define print(x) std::cout<<x<<std::endl;
class Node
{
public:
int data;
Node* next;
};
class LinkedList
{
private:
Node** head_ref;
public:
LinkedList() :head_ref(NULL) {};
void insertFront(int new_data)
{
Node* new_node = new Node();
new_node->data = new_data;
if(this->head_ref == NULL)
this->head_ref = &new_node;
else
{
new_node->next = *(this->head_ref);
this->head_ref = &new_node;
}
}
void PrintLinkedList()
{
Node* temp = (*(this->head_ref));
while (temp->next != NULL)
{
print(temp->data);
}
print("\n");
}
};
int main()
{
LinkedList a1;
a1.insertFront(5);
a1.insertFront(6);
a1.insertFront(7);
a1.PrintLinkedList();
std::cin.get();
}
As you will see in the screenshots in the watch1 tab the this->head_ref preserves the location of the Node* but Node* i.e. (*(this->head_ref)) doesn't preserve the location of the Node. I want to know what is causing this. Is it because Node** head_ref has no regulation in how the inside pointer points to the Node or is it a scope problem? The problem occurs each time right after the next function call happens and the debugger enters the insertFront function, the Node* becomes a free pointer pointing to nothing.
First call screenshot
Second call screenshot before entering insertFront
Second call screenshot just after entering insertFront but a new Node object has not been made yet
The answer is provided by #IgorTandetnik in the comments.
The Node object is allocated on the heap. But the Node* object named new_node is allocated on the stack. You have head_ref point to new_node and new_node point to the Node object. Then the function returns, new_node is gone, and there is no longer any connection between head_ref and the heap-allocated Node. head_ref points to some garbage value where new_node used to be, and Node on the heap is leaked as nothing points to it anymore.
I have changed the code accordingly by using Node* head_ref which will refer to a heap allocated Node instead of the new_nodepointer which goes out of scope.
#include<iostream>
#define print(x) std::cout<<x<<std::endl;
class Node
{
public:
int data;
Node* next;
};
class LinkedList
{
private:
Node* head_ref;
public:
LinkedList() :head_ref(NULL) {};
void insertFront(int new_data)
{
Node* new_node = new Node();
new_node->data = new_data;
if(this->head_ref == NULL)
this->head_ref = new_node;
else
{
new_node->next = this->head_ref;
this->head_ref = new_node;
}
}
void PrintLinkedList()
{
Node* temp = this->head_ref;
while (temp->next != NULL)
{
print(temp->data);
temp = temp->next;
}
print(temp->data);
print("\n");
}
};
int main()
{
LinkedList a1;
a1.insertFront(5);
a1.insertFront(6);
a1.insertFront(7);
a1.PrintLinkedList();
std::cin.get();
}

Why can't I insert nodes after head into a C++ linked list?

Could someone please help me identify the problem with the code below.
#include <iostream>
using namespace std;
struct node
{
int a,b;
struct node* next=NULL;
};
node* head=NULL;
void insert(int a,int b)
{
if(head==NULL)
{
head=new node;
head->a=a;
head->b=b;
return;
}
node* cur=head;
while(cur!=NULL)
{
cur=cur->next;
}
cur=new node;
cur->a=a;
cur->b=b;
return;
}
void display()
{
node* cur=head;
while(cur!=NULL)
{
cout<<cur->a<<"\t"<<cur->b<<"\n";
cur=cur->next;
}
}
int main()
{
int i;
for(i=0;i<3;++i)
{
insert(i,i+1);
}
display();
//cout<<h->next->a;
return 0;
}
This is the output that I get:
0 1
It seems that I can only display the head node and none after gets inserted. If I try to access the next node after head, I get a segmentation fault. Why is that?
Your search code is:
node* cur=head;
while(cur!=NULL)
{
cur=cur->next;
}
cur=new node;
At the end of the loop, you've found the right place to add the new node, but you overwrite that with cur = new node; — so you need to use something more like:
node *new_node = new node;
new_node->a = a;
new_node->b = b;
new_node->next = nullptr;
cur->next = new_node;
Or, equivalently:
cur->next = new node;
cur->next->a = a;
cur->next->b = b;
cur->next->next = nullptr;
Even better, you'd create a constructor for the struct node class, such as:
node(int a_init = 0, int b_init = 0) : a(a_init), b(b_init), next(nullptr) { }
and then:
cur->next = new node(a, b);
would do the whole initialization job.
While inserting, update head->next to NULL (when head is NULL)
and curr->next to NULL (when some elements are already in the list)
respectively.
You are not linking head to curr. To link head and curr, you can
create another pointer instead to hold the new element, say new_ptr.
Keep curr such that curr->next=NULL, and then write
curr->next=new_ptr.
void insert(int a,int b)
{
if(head==NULL)
{
head=new node;
head->a=a;
head->b=b;
head->next=NULL;
return;
}
node* cur=head,*new_ptr;
while(cur->next!=NULL)
{
cur=cur->next;
}
new_ptr=new node;
new_ptr->a=a;
new_ptr->b=b;
new_ptr->next=NULL;
curr->next=new_ptr;
return;
}
I found out the bug .While inserting , instead of sitting in a node and checking if it is null , look 1 node ahead and check if its null. Because if you don't , then the list will get broken and cpp allocates memory else where rather than to the pointer of the last list node's next branch.
Modified insert function :
void insert(int a,int b)
{
if(head==NULL)
{
head=new node;
head->a=a;
head->b=b;
head->next=NULL;
return;
}
node* cur=head;
while(cur->next!=NULL)
{
//cout<<cur->a<<"\t"<<cur->b<<"\n";;
cur=cur->next;
}
cur->next=new node;
cur->next->a=a;
cur->next->b=b;
return;
}
At the time of creation of any node , the next pointer of that node becomes null as per the definition of your node.
struct node
{
int a,b;
struct node* next=NULL;
};
Now,after the creation of start node ,the next pointer of start node is NULL.And when u created your second node ,you didn't point the next node of your first node to the second node.Then how will you be able to reach to the second node if you do not have the pointer to the second node.
So the solution will be --
void insert(int a,int b)
{
node *temp;
if(head==NULL)
{
head=new node;
head->a=a;
head->b=b;
temp=head;
return;
}
node* cur=head;
while(cur!=NULL)
{
cur=cur->next;
}
cur=new node;
temp->next=cur;
cur->a=a;
cur->b=b;
temp=cur;
return;
}

display function Link-list code not working

im trying to add node at the starting of linked list but in my code it only displaying the last element which i have entered only the last element .what is the problem why this is happening
#include <stdio.h>
//node structure
struct node
{
int data;
struct node *next;
};
//struct
//datatype declaration
typedef struct node node ;
// head pointer which will indicate starting point of link list
node *head;
//create fuction that will insert values into note and its next pointer field
void create(int num);
//display function will display the link list
void display();
main()
{
int num,i,n;
printf("enter the nno of node to create : ");
scanf("%d",&n);
for(i=0;i<n;++i)
{
printf("enter data for node %d= ",i+1);
scanf("%d",&num);
create(num);
}
display();
//display call
}
void create(int num)
{
head=NULL;
node *temp;
temp=(node*)malloc(sizeof(node));
temp->data=num;
temp->next=head;
head=temp;
return;
}
//function create() end
void display()
{
node *temp1;
temp1=head;
while(temp1!=NULL)
{
printf("data : %d-> ",temp1->data);
temp1=temp1->next;
}
return;
}
//fucntion display() end
Your main problem is:
head=NULL;
Thus your line
temp->next=head;
always sets the next to be NULL. Thus all your lists are
of length one.
I would suggest either declaring head to be static (and
hence zeroed from the outset), or intializing head in main.
Your display function seems fine, your create function should look something like this:
void create(int num)
{
node* temp = new node();
if(head ==NULL)
{ temp->data = num;
head = temp;
head->next = NULL;
}
else if(head->next == NULL)
{
temp->data = num;
head->next = temp;
}
else
{
node* temp2 = head;
while(temp2->next !=NULL)
{ temp2 = temp2->next;
}
temp->data = num;
temp2->next = temp;
}
return;
}
This create function above will place the node depending if the list is empty, has one node, or more than one node will insert at Last position. You can now go off this to insert in front of head, or in Link list terms function (InsertBeforeFirst). And of course where you have node* head up top should be initialized to NULL;

C++, Allocate memory, Segmentation fault: 11

#include <iostream>
using namespace std;
class Node
{
public:
Node(int N, Node *l, Node *r);
int value; // stored value
Node *left; // left node
Node *right; // right node
};
Node::Node(int N, Node *l, Node *r){
value = N;
left = l;
right = r;
}
void insert(Node *x){
if (x == nullptr) {
Node newNode(5, nullptr, nullptr);
*x = newNode;
}
}
int main(){
Node *root;
root = nullptr;
insert(root);
cout << root->value << endl;
return 0;
}
This is the beginning of a binary search tree. In the insert function, I am trying to change a nullptr to a pointer pointing to a Node object. When I run this c++ code, I get the error: "Segmentation fault: 11". After doing some research, I believe I need to (re)allocate memory. How can I allocate the memory inside of the insert function, if possible?
First up I presume
if (x == nullptr) {
Is a typo? Didn't you mean
if (x != nullptr) {
??
If it is null you shouldn't be going ahead and dereferencing it.
How you fix the crash really depends on how you want the interface to your BST to be.
You are passing in a nullptr and attempting to assign to it. This wont work. You can't assign to nothing.
So you could do something like.
#include <iostream>
using namespace std;
class Node
{
public:
Node(int N, Node *l, Node *r);
int value; // stored value
Node *left; // left node
Node *right; // right node
};
Node::Node(int N, Node *l, Node *r){
value = N;
left = l;
right = r;
}
void insert(Node *x){
if (x != nullptr) {
Node newNode(5, nullptr, nullptr);
*x = newNode;
}
}
int main(){
Node root(2, nullptr, nullptr);
insert(&root);
cout << root.value << endl;
return 0;
}
Here you have an initial object, allocated on the stack, which you can assign to in insert. If you use this method you are wasting some time doing the initial construction of root in function main, when you are always going to go and assign over it.
If you wanted to persist with heap allocation of the Node. Pass a pointer to pointer to insert e.g.
#include <iostream>
using namespace std;
class Node
{
public:
Node(int N, Node *l = nullptr, Node *r = nullptr);
int value; // stored value
Node *left; // left node
Node *right; // right node
};
Node::Node(int N, Node *l, Node *r)
: value(N), left(l), right(r)
{}
void insert(Node **x)
{
if (x != nullptr)
{
Node* n = new Node(5);
*x = n;
}
}
int main()
{
Node *root = nullptr;
insert(&root);
if(root)
{
cout << root->value << endl;
delete root;
}
return 0;
}
This lets insert manage the allocation of the node.
Have you tried to run valgrind? It's a good idea with these kind of errors (and even if you don't see them), it sometime detects error before the symptoms gets visible (the segmentation fault might be just a consequence of an earlier error - if it's not a normal debugger will stop where the segmentation fault occurs).
It points at the fault directly:
void insert(Node *x){
if (x == nullptr) {
Node newNode(5, nullptr, nullptr);
*x = newNode; <<<--- here
}
}
So you basically check if x is null and if it is you tries to dereference and write to the pointed object? That sounds really bad. You're supposed to do the opposite - check and if it's null you do not dereference the pointer.

Implementing a double linked list in C++, pointers and odd values

I'm pretty rusty in C++ and I'm trying to implement a double linked list but I am having some reading violations and having some odd values being given.
#include <iostream>
struct Node
{
int val;
Node* next;
Node* prev;
};
class linkedList
{
public:
linkedList(); //constructor
~linkedList(); //destructor
void push_back(int x);
void addtofront(int x);
//void deleteNode(int x);
bool isempty();
void firstelem();
void prnt_tail();
/*void insert_after(int x, int y);
void insert_before(int x, int y);*/
private:
Node* head;
Node* next;
Node* prev;
};
linkedList::linkedList(){};
linkedList::~linkedList(){};
void linkedList::push_back(int x)
{
linkedList* list = this;
Node temp;
temp.val=x;
temp.next=NULL;
temp.prev=NULL;
if (!head)
{
linkedList* list = new linkedList();
list->head;
head = new Node;
head->val = x;
head->next = NULL;
head->prev = NULL;
}
else
{
Node* temp1;
temp1=head;
while (temp1->next!=NULL)
{
temp1 = temp1->next;
}
temp.next= NULL;
temp.prev=temp1;
temp.val = x;
}
};
void linkedList::addtofront(int x)
{
linkedList* list = this;
Node temp;
temp.val=x;
temp.next=NULL;
temp.prev=NULL;
if (!head)
{
linkedList* list = new linkedList();
list->head;
head = new Node;
head->val = x;
head->next = NULL;
head->prev = NULL;
}
else
{
list->head->prev=&temp;
temp.next=head;
head=&temp;
}
};
//void linkedList::deleteNode(int x)
//{
// if(head)
// {
// linkedList *ptr = head;
// while(ptr->node.val != x)
// {
// ptr = ptr->node.next;
// }
// (ptr->node.next)->prev=ptr->node.prev;
// ptr->node.prev=ptr->node.next;
// delete ptr;
// }
// else
// std::cout<<"empty list";
//}
bool linkedList::isempty()
{
if(head)
return false;
else return true;
};
void linkedList::firstelem()
{
std::cout<<head->val;
};
void linkedList::prnt_tail()
{
if(head)
{
Node *temp;
temp=head;
temp=head->next;
std::cout<<temp;
while(temp->next!=NULL)
{
std::cout<<temp->val<<" ";
}
std::cout<<temp->val;
}
else
{
std::cout<<"empty list";
}
};
//linkedList::insert_after(int x, int y)
//{
//
//}
//
//linkedList::insert_before(int x, int y)
//{
//
//}
and my main
#include "linkedlist2.h"
#include <stdlib.h>
#include <iostream>
int main()
{
linkedList example;
if(example.isempty())
std::cout<<"this list is empty "<<"\n";
else
std::cout<<"this list is not empty"<<"\n";
for (int i = 1; i<=20; i++)
{
example.push_back(i);
//example.prnt_tail();
}
example.addtofront(25);
example.firstelem();
std::cout<<"\n";
example.addtofront(28);
example.firstelem();
std::cout<<"\n";
if(example.isempty())
std::cout<<"this list is empty "<<"\n";
else
std::cout<<"this list is not empty"<<"\n";
//example.push_back(26);
//std::cout<<example.head->next->val;
example.firstelem();
std::cout<<"\n";
example.prnt_tail();
std::cout<<"\n";
system("pause");
}
when I run main I get
this list is empty
-858993460
-858993460
this list is not empty
-858993460
CCCCCCCC
I also get the error
Access violation reading location 0xCCCCCCD0.
and the next statement to be executed is the while loop in "void linkedList::prnt_tail()"
I'm fairly sure my problem is in my pointers and all that. Like I said, I'm really rusty so any help you can give would be greatly appreciated, even in things not directly related to my problems.
So, there's a lot of problems in this code. Let's see what we can do:
It's odd that you have next and prev members in both your node objects and your linkedList objects. Let's fix this by making the linkedList object point to the first node (that is, the head node), and then use the members in each node to point to the next object.
This means that we have:
struct Node {
int val;
struct Node* next;
struct Node* prev;
};
class linkedList {
public:
linkedList(); //constructor
~linkedList(); //destructor
void push_back(int x);
void addtofront(int x);
bool isempty();
private:
Node* head;
};
Let's fix a number of errors in your push_back. First, no matter what the state of the linkedList is, we need to create a new Node on the heap, and then we will be placing that Node somewhere in the linkedList.
void linkedList::push_back(int x)
{
Node *node = new Node;
node->next = NULL;
node->prev = NULL;
node->val = x;
if (head == NULL) {
head = node;
} else {
Node *last = head;
while (last->next != NULL)
last = last->next;
last->next = node;
node->prev = last;
}
}
We also need to fix push_front. This code should look somewhat similar to push_back.
void linkedList::addtofront(int x)
{
Node *node = new Node;
node->next = NULL;
node->prev = NULL;
node->val = x;
if (head == NULL) {
head = node;
} else {
node->next = head;
head->prev = node;
head = node;
}
}
If you're going to write a constructor, you probably should do that correctly:
linkedList() {
head = NULL;
}
It's also worth noting that you will want a real destructor to clean up all of these objects that you are creating on the heap. And then you also need to implement the copy constructor and assignment operator.
Apart from a extra useless semicolon, this looks wrong:
linkedList::linkedList(){};
A constructor is supposed to provide initial values for members, and you haven't done so. Leaving pointer members uninitialized is very bad style, and is the cause of many of your problems.
Because these members aren't initialized, when you later read from them (e.g. isEmpty()'s test if (head)) it will be undefined behavior.
To start with, in addToFront and push_back you probably do not want to be creating new linked lists on the heap. You already have a linked list (the one the method is currently being run on) which you want to modify. Don't create new linked lists here.
However, you DO want to create new Nodes on the heap, never on the stack. In at least one place you create a node on the stack, eg
Node temp;
And then later store and use a pointer to that object. As soon as the function quits, that variable is gone and that pointer is pointing to garbage.
in linked list class , (Node* next;) and (Node* prev;) are extera