I am working on simple linked list project, everything works fine except List class destructor. I am trying to delete every Node that list has but g++ throws Segmentation Fault everytime(even for empty destructor). Can someone help me, what is wrong with my code? Thanks!.
My List header;
struct Node{
double data;
Node* next;
};
class List{
public:
List();
~List();
void insertF(double data);
void printList();
private:
Node* head;
Node* currNode;
};
List source file;
#include "List.h"
List::List(){
std::cout<<"Constructed Linked List";
}
void List::insertF(double dataX){
Node* nn = new Node;
if(!currNode){
head = nn;
nn->data=dataX;
currNode = nn;
}else{
currNode->next = nn;
nn->data = dataX;
currNode = nn;
}
}
void List::printList(){
Node* walker = head;
while(walker){
std::cout<<walker->data;
std::cout<<"----->";
walker = walker->next;
}
}
List::~List(){
Node* currNode = head, *nextNode = NULL;
while(currNode != NULL){
nextNode = currNode->next;
delete currNode;
currNode = nextNode;
}
std::cout<<"sd";
}
Main;
#include "List.h"
using namespace std;
int main(){
List list;
list.insertF(3.0);
list.insertF(4.0);
list.printList();
}
Even;
List::~List(){
std::cout<<"sd";
}
Throws segmentation fault. List is always filled so I dont check if head is empty
You invoked undefined behavior by using values of the member variables head and currNode without initialization.
Initialize them like this:
List::List(){
head = nullptr; // add this
currNode = nullptr; // add this
std::cout<<"Constructed Linked List";
}
Or like this:
List::List() : head(nullptr), currNode(nullptr) { // add member initialization list
std::cout<<"Constructed Linked List";
}
You have not initialized currNode anywhere, so when you do:
if(!currNode) {
the first time insertF is called, this use of currNode invokes undefined behavior.
You should initialize all your members like this:
Node* head = nullptr;
Node* currNode = nullptr;
Related
I have given insert and a print function to insert data in a linked list and then print it.
But somehow it does not give any output and keeps running for a infinite time.
What is wrong?
Here is the code I have written. This is a simple program to create a linked list using loops and functions.
#include<iostream>
using namespace std;
struct node{
int data;
struct node* next;
};
struct node* head;
void insert(int data){
struct node* temphead=head;
if (temphead == NULL)
{
node* temp = new node();
temp->data=data;
temp->next=NULL;
while (temphead == NULL){
head==temp;
}
}
else if (temphead != NULL)
{
node* temp = new node();
temp->data=data;
temp->next=NULL;
while (temphead != NULL)
{
temphead->next= temp;
temphead=temphead->next;
}
}
}
void print(){
struct node* tempptr = head;
while (tempptr->next != NULL)
{
cout<<tempptr->data<<"_";
tempptr=tempptr->next;
}
}
int main(){
head=NULL;
insert(2);
insert(4);
insert(8);
insert(6);
//list - 2_4_8_6
print();
return 0;
}
There were few bugs in your code and also typos. Please read the comments marked with // CHANGE HERE for the description of the changes I did:
#include <iostream>
using namespace std;
struct node{
int data;
struct node* next;
};
struct node* head;
void insert(int data){
struct node* temphead = head;
if (temphead == nullptr)
{
node* temp = new node();
temp->data = data;
temp->next = nullptr;
// CHANGE HERE: removed unnecessary while loop
// Directly assign temp to head
head = temp;
}
else
{
node* temp = new node();
temp->data=data;
temp->next=nullptr;
// CHANGE HERE: check for temphead->next instead of temphead
while (temphead->next != nullptr)
{
// CHANGE HERE: remove unnecessary line: temphead->next= temp;
temphead=temphead->next;
}
// CHANGE HERE: assign temp to temphead->next (i.e. to last node)
temphead->next = temp;
}
}
void print(){
struct node* tempptr = head;
// CHANGE HERE: check for tempptr instead of tempptr->next
while (tempptr != nullptr)
{
cout<<tempptr->data<<"_";
tempptr=tempptr->next;
}
}
int main(){
head=nullptr;
insert(2);
insert(4);
insert(8);
insert(6);
//list - 2_4_8_6
print();
return 0;
}
NOTE: Your code uses new for dynamic memory allocation but doesn't use delete to de-allocate the memory when not required. If you want to avoid using new/delete, you can explore about smart pointers.
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.
I am a beginner and am working on Linked list. I am trying to make a program which adds elements to the list, updates the list, dislays it and deletes it.I am getting an exception : read access violation. temp was 0xDDDDDDDD.
I think there is some problem with display() function. The debugger also does shows the same.
#include "stdafx.h"
#include "Node.h"
#include<iostream>
using namespace std;
Node::Node() //constructor
{
head = NULL;
}
Node::~Node() //destructor
{
}
void Node::addFirstNode(int n) //adding the first element in the list
{
node *temp = new node;
temp->data = n;
temp->next = NULL;
head = temp;
}
void Node :: addLast(int n) //Adding elements at the end of the list
{
node *last = new node;
last->data = n;
last->next = NULL;
node *temp = new node;
temp = head;
while (temp->next != NULL) {
temp = temp->next;
}
temp->next = last;
}
void Node::display() //Displaying the list
{
node *temp = head;
while (temp != NULL)
{
cout<<temp->data;
temp = temp->next;
}
}
//the main function:
#include "stdafx.h"
#include "Node.h"
#include<iostream>
using namespace std;
int main()
{
Node a;
a.addFirstNode(101); //Calling function : addFirstNode
a.addLast(102); //Calling function : addLast
a.addLast(103); //Calling function : addLast
a.addLast(104); //Calling function : addLast
a.display(); //Calling function : display
return 0;
}
The Node.h file is as below:
struct node
{
int data;
node *next;
};
class Node
{
private :
node *head;
public:
Node();
~Node();
void addFirstNode(int n);
void addLast(int n);
void display();
};
You should rename Node to better describe what it is, e.g. List.
In Node::addFirst(), replace temp->next = NULL; with temp->next = head; You don't want to throw away your list every time you add a Node to the beginning of it.
In Node::addLast(), replace node *temp = new node; with node *temp = head; You don't want to leak memory every time you add a Node to the end of it.
I am refreshing my c++ by creating a simple linked list class. What I am having problems is when I try to print the list, there is a zero printing at the beginning of the list. How can I get rid of this? Also, I am having trouble with my second constructor. How would I go about this?`
Here is the code
List.h
#ifndef NODE_H
#define NODE_H
class List{
private:
typedef struct Node{
int data;
struct Node* next;
}* node;
node head;
int listLength;
public:
List();
List(int data, node nextLink);
void printList();
void push(int data);
void Delete(int d);
int listSize(void);
};
my List.cpp
#endif
#include "node.h"
#include <iostream>
using namespace std;
List::List(){
head->data=0;
head->next= NULL;
listLength=0;
}
List::List(int data, node nextLink){
head=NULL;
listLength++;
}
void List::push(int data){
if(head==NULL){
head->data=data;
head->next= NULL;
}
else{
node cursor = head;
while(cursor->next != NULL)
cursor = cursor -> next;
node newNode= new Node;
newNode->data=data;
newNode->next=NULL;
cursor->next= newNode;
}
listLength++;
}
void List::printList(){
node cursor=head;
while(cursor!=NULL){
//if(cursor->data==0){cursor=cursor->next;}
if(cursor->next==NULL){
cout<<cursor->data<<endl;
return;
}
else{
cout<<cursor->data<<" -> ";
cursor=cursor->next;
}
}
cout<<endl;
}
int main(){
List li;
li.push(2);
li.push(3);
li.push(0);
li.push(4);
li.printList();
return 0;
}
You never initialize your head node, so you're writing to unallocated memory in the code below.
if(head==NULL){
head->data=data;
head->next= NULL;
}
It should be:
if(head==NULL){
head = new Node; // added this line
head->data=data;
head->next= NULL;
}
You also probably want the first constructor
List::List(){
head->data=0;
head->next= NULL;
listLength=0;
}
to instead be
List::List(){
head = NULL;
listLength=0;
}
As for the second constructor, I assume you want something like this?
List::List(int data, node nextLink){
head = new Node;
head->data = data;
head->next = nextLink;
listLength = 1;
}
If not, could you better explain what you want?
I would also note that it would be generally considered good programming practice to create a constructor for the Node struct that initializes next to NULL, and then you wouldn't have to set it explicitly every time you create a new Node throughout your code.
i created a linked list : struct Node and List Class and i used it outside with my main method,
#include "Lists.cpp"
#include <cstdlib>
using namespace std;
int main(){
Lists l = new Lists(1);
l.add(2);
l.add(3);
l.add(4);
l.add(5);
system("pause");
return 0;
}
but it produces an error that says "invalid conversion from List* to int". Is my using of outside class right? Im a little confused how I will solve this.
#include <cstdlib>
#include <iostream>
using namespace std;
struct Node{
int data;
Node *next;
Node(int i){
data = i;
next = NULL;
}
};
class List{
Node *head;
public:
List(int i){
head = new Node(i);
}
void addToHead(int i){
Node *temp = new Node(i);
temp->next = head;
head = temp;
}
void add(int i){
Node *currNode = head;
while(currNode!= NULL){
if(currNode->next == NULL){
currNode->next = new Node(i);
break;
}
else{
currNode = currNode-> next;
}
}
}
void deleteNode(int i){
Node *currNode = head;
Node *prevNode = NULL;
while(currNode!= NULL){
if(currNode->data == i) {
if(prevNode== NULL){
head = head->next;
}
else{
prevNode->next = currNode->next;
}
}
prevNode = currNode;
currNode = currNode -> next;
}
}
void insert(int position, Node *n){
Node *currNode= head;
Node *prevNode = NULL;
for(int counter = 0; counter>= position && currNode!= NULL; counter++){
if(counter==position){
Node *temp = currNode;
n->next = currNode;
prevNode->next= n;
}
prevNode = currNode;
currNode = currNode-> next;
}
}
void traverse(Node *node){
if(node!=NULL){
cout<< node-> data <<endl;
traverse(node->next);
}
}
};
Lists l = new Lists(1);
should be:
Lists *l = new Lists(1);
new provides a pointer.
The reason you get that specific error is that the line would be valid if the conversion chain Lists * -> int -> Lists were valid. The second is valid here because of the constructor but the first is not.
At which line do you get the mentionned error ? At first glance, Lists l = new Lists(1); is already wrong : Lists* l = new Lists(1); would be correct.
But this error does not correspond to the one you mention. Also note that you're defining List and trying to use Lists.
Is this the code you're trying to compile ?
Use List *l = new List(1); or std::shared_ptr<List> l = make_shared<List>( 1 ); if you want a dynamically-allocated List.
Or List l(1); if you want a List with automatic storage duration.
Be careful with the names, in the class definition you use List, and in the main function you use Lists.