Linked-list program crashing after adding elements - c++

My program crashes after sequence of inserting head, then inserting tail, every other cases it seems to work. I cant figure it out.
struct Node {
int key;
Node *next;
};
struct List {
Node *head, *tail;
};
void init(List& l) {
l.head = l.tail = NULL;
}
void insertHead(List& l, int x) {
Node *temp=new Node;
temp->next=NULL;
temp->key=x;
temp->next=l.head;
l.head=temp;
}
void insertTail(List& l, int x) {
Node *temp=new Node;
temp->key=x;
temp->next=NULL;
if(l.head==NULL) {
l.head = temp;
l.tail = temp;
} else {
l.tail->next=temp;
l.tail=temp;
}
}
Thats only part of my code, but I think it will be enough, otherwise here is remaining part http://pastebin.com/WxmYJ0uE

You forgot to set the tail when the first element in the list in inserted.
void insertHead(List& l, int x) {
Node *temp=new Node;
temp->next=NULL;
temp->key=x;
temp->next=l.head;
l.head=temp;
if(l.tail == NULL) l.tail = l.head; // <-- you forgot this
}

Related

implementing a linked list and it doesn't produce output

I am implementing a linked list but it doesn't display any output.
implementing a linked list with 4 elements and making fuction insert and insertathead and display.
#include <bits/stdc++.h>
using namespace std;
// class node to make node element.
class node
{
public:
int data;
node *next;
node{
}
// constructor
node(int val)
{
data = val;
next = NULL;
}
// function to insert element at head.
void insertAthead(node *&head, int val)
{
node *n = new node(val);
n->next = head;
head = n;
return;
}
// function to insert in linked list.
void insert(node *head, int val)
{
node *temp = head;
if (head == NULL)
{
insertAthead(head, val);
return;
}
node *n = new node(val);
while (temp->next != NULL)
{
temp = temp->next;
}
temp->next = n;
}
// function to display each element in a linked list.
void display(node *head)
{
while (head->next != NULL)
{
cout << head->data;
head = head->next;
}
cout << head->data;
}
};
//main function
int main()
{
node *head; // line at which I think there is a problem
head->insert(head, 1);
head->insert(head, 2);
head->insert(head, 3);
head->insert(head, 4);
head->display(head);
return 0;
}
I think the problem is at line 1
node *head;
when I change this line with node *head=new node(any integer value) the code runs fine.
First you want to move insert, insertAtHead and display out of the Node class. These are list functions have have no need of special access to Node.
Also you should initialise head to NULL (representing the empty list).
This means changing main like this
node *head = NULL;
insert(head, 1);
insert(head, 2);
insert(head, 3);
insert(head, 4);
display(head);
Then you want to change
void insert(node *head, int val)
to
void insert(node *&head, int val)
Just like you have done (correctly) with insertAtHead.
If you wanted to take this further you could create a List class, along these lines
class List
{
public:
List() { root = NULL; }
void insert(int val);
void insertAtHead(int val);
void display();
private:
Node* root;
};
then main would look like this
int main()
{
List l;
l.insert(1);
l.insert(2);
l.insert(3);
l.insert(4);
l.display();
}

Linked List insertion isn't working in for/while loop

I am learning DSA, and was trying to implement linked list but the insertion function that i wrote is not
working in a for or while loop, its not the same when i call that function outside the loop, it works that way. I am not able to figure it out, please someone help me.
#include <iostream>
class Node {
public:
int data;
Node *next;
Node(int &num) {
this->data = num;
next = NULL;
}
};
class LinkedList {
Node *head = NULL;
public:
void insert(int num) {
Node *tmp;
if (head == NULL) {
head = new Node(num);
tmp = head;
} else {
tmp->next = new Node(num);
tmp = tmp->next;
}
}
void printList() {
Node *tmp = head;
while (tmp) {
std::cout << tmp->data << " ";
tmp = tmp->next;
}
std::cout << std::endl;
}
void reverseList() {
Node *curr = head, *prev = NULL, *nextNode;
while (curr) {
nextNode = curr->next;
curr->next = prev;
prev = curr;
curr = nextNode;
}
head = prev;
}
};
int main() {
LinkedList list1;
// This is not working
int num;
while (num != -1) {
std::cin >> num;
list1.insert(num);
}
// This is working
// list1.insert(1);
// list1.insert(2);
// list1.insert(3);
// list1.insert(4);
// list1.insert(5);
list1.printList();
list1.reverseList();
list1.printList();
return 0;
}
I expect this after insertion
Edit:
although #Roberto Montalti solved this for me, but before that I tried passing incrementing value using a for loop which worked but as soon as I pull that cin out it crashes. can someone tell me what's happening under the hood?
for (int i = 1; i <= 10; i++)
{
list1.insert(i);
}
When inserting the nth item (1st excluded) tmp is a null pointer, i don't understand what you are doing there, you are assigning to next of some memory then you make that pointer point to another location, losing the pointer next you assigned before, you must keep track of the last item if you want optimal insertion. This way you are only assigning to some *tmp then going out of scope loses all your data... The best way is to just keep a pointer to the last inserted item, no need to use *tmp.
class LinkedList
{
Node *head = NULL;
Node *tail = NULL;
public:
void insert(int num)
{
if (head == NULL)
{
head = new Node(num);
tail = head;
}
else
{
tail->next = new Node(num);
tail = tail->next;
}
}
...
}
You need to loop until you reach the end of the list and then add the new node after that. Like this.
void insert(int num) {
Node *tmp = head;
if (head == NULL) {
head = new Node(num);
}
else {
while (tmp->next != NULL) {
tmp = tmp->next;
}
tmp->next = new Node(num);
}
}
first of all you need to define a node for each of the tail and head of the list as follows
Node *h;
Node *t;
you may also separate the Node from the LinkedList class so you can modify easily
class Node{
public:
int data;
Node *next;
Node(int data, Node* next);
~Node();
};
Node::Node(int data, Node* next)
{
this->data= data;
this->next= next;
}
Node::~Node(){}
}
after that you can try to add these functions to your LinkedList class
so it can deal with other special cases such empty list or full, etc..
void addToHead(int data){
Node *x = new Node(data,h);
h=x;
if(t==NULL){
t=x;
}
void addToTail(int data){
Node *x = new Node(data,NULL);
if(isEmpty()){
h=t=x;
}
else
{
t->next=x;
t=x;
}
}
now for the insert function try this after you implemented the Node class and the other functions,
void insert(int v){
if(h==nullptr){addToHead(v); return;}
if(h->data>=v) {addToHead(v);return;}
if(t->data<=v) {addToTail(v); return;}
// In this case there is at least two nodes
Node *k=h->next;
Node *p=h;
while(k != nullptr){
if(k->data >v){
Node *z =new Node(v,k);
p->next=z;
return;
}
p=k;
k=k->next;
}
}
the idea of making all of this is not lose the pointer when it goes through elements in the Linked List so you don't end up with a run time error.
I hope this can be useful to you.
There was an issue with your insert function.
Read about segmentation fault here https://www.geeksforgeeks.org/core-dump-segmentation-fault-c-cpp/#:~:text=Core%20Dump%2FSegmentation%20fault%20is,is%20known%20as%20core%20dump.
for a quick workaround you can use this
using namespace std;
#include <iostream>
class Node
{
public:
int data;
Node *next;
Node(int num)
{
this->data = num;
next = NULL;
}
};
class LinkedList
{
Node *head = NULL;
public:
void insert(int num)
{
Node *tmp= new Node(num);
tmp->next=head;
head=tmp;
}
void printList()
{
Node *tmp = head;
while (tmp)
{
std::cout << tmp->data << " ";
tmp = tmp->next;
}
std::cout << std::endl;
}
void reverseList()
{
Node *curr = head, *prev = NULL, *nextNode;
while (curr)
{
nextNode = curr->next;
curr->next = prev;
prev = curr;
curr = nextNode;
}
head = prev;
}
};
int main()
{
LinkedList list1;
// This is not working
int num,i=0,n;
cout<<"Type the value of n";
cin>>n;
while (i<n)
{
cin >> num;
cout<<num<<" "<<&num<<endl;
list1.insert(num);
i++;
}
list1.printList();
list1.reverseList();
list1.printList();
return 0;
}

singleLinkedlist c++ segmentation fault core dumped

I am trying to create a single linked list but the above code is giving an error: segmentation fault core dumped. I am inserting elements 5,9,12 in the singlelinkedlist and displaying the list. First I create a node and then class singlelinkedlist with all the methods. I am still trying to learn basics.
#include <iostream>
using namespace std;
class Node
{
public:
int data;
Node* next;
Node()
{
}
Node(int element)
{
data = element;
next=NULL;
}
Node(int element, Node* link)
{
data = element;
next = link;
}
};
class SingleLinkedList
{
public:
Node* head;
int listsize = 0;
Node* curr;
bool isempty()
{
return head==NULL;
}
void Insert(int data)
{
Node* new_node = new Node(data);
if(isempty())
{
head = new_node;
listsize++;
return;
}
curr = head;
while(curr->next!=NULL)
{
curr->next=curr;
}
curr->next=new_node;
listsize++;
}
void display()
{
curr = head;
while(curr!=NULL)
{
cout<<curr->data<<"-->";
curr=curr->next;
}
}
};
int main()
{
SingleLinkedList l1;
l1.Insert(5);
l1.Insert(9);
l1.Insert(12);
l1.display();
}
Try to change:
while (curr->next != NULL)
{
curr->next = curr;
}
to:
while (curr->next != NULL)
{
curr = curr->next;
}
for you list traversal while doing node insertion to avoid infinite loop
The pointer head is not initialized. Its value is not garanteed to be nullptr. Your code is therefore UB, since the first insert in the list will invoke isempty(), which is using this uninitialised pointer.
When this is done, consider also Anon’s answer.

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

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