unable to assign value to a struct attribute. C++ - c++

I am trying to implement a linked list in C++. I have the following code
class LinkedList {
private:
struct node {
int data;
node* next;
}*
head;
node* mkNode(int data, node* next){
node* n;
n->data = data;
n->next = next;
return n;
}
public:
LinkedList(){
head = NULL;
}
void insertAtHead(int data){
head = mkNode(data, head);
}
};
I am getting a segmentation fault: 11 on the lines n->data = data; and n->next = next; inside the mkNode() function. any idea why?

node* mkNode(int data, node* next)
{
node* n;
n->data = data;
n->next = next;
return n;
}
pointer 'n' to 'node' is not initialized. Try to initialize it with struct node memory.
node* n = new struct node;

Your pointer is not initialized.
Creating an Object on heap will solve this, don't forget to free the memory after use.
node* mkNode(int data, node* next){ return new node({data,next}); }

Related

free(): double free detected in tcache 2, in linked List deletion of a node in c++ and how destructor is working in this code

class Node{
public:
int data;
Node* next;
Node(int d){
data = d;
next = NULL;
}
~Node(){
delete next;
}
};
class List{
public:
Node* head;
Node* tail;
List(){
head = NULL;
tail = NULL;
}
~List(){
delete head;
}
void push_back(int data){
Node* n = new Node(data);
if(head == NULL){
head = tail = n;
}else{
tail->next = n;
tail = n;
}
}
void print(){
Node* temp = head;
while(temp != NULL){
cout<<temp->data<<" ";
temp = temp->next;
}
}
void deleteNode(int d){
Node* curr = head;
Node* prev = NULL;
while(curr != NULL){
if(curr->data == d){
if(prev == NULL){
head = head->next;
delete curr;
break;
}else{
prev->next = curr->next;
curr->next = NULL;
delete curr;
break;
}
}
prev = curr;
curr = curr->next;
}
}
};
int main(){
List l;
l.push_back(1);
l.push_back(2);
l.push_back(3);
l.push_back(4);
l.push_back(5);
l.deleteNode(1);
l.print();
}
If I delete 1 from 1->2->3->4->5
Expected Output: 2->3->4->5
Output: free(): double free detected in tcache 2;
Reason: Destructor in Node Class. If I remove it is working fine.
Doubt : If I remove destructor in Node class in Node class then how can I free up memory. And can anyone also explain how destructors are working in both Node and List class.
Can someone please help me with this, or can provide alternative solution.
Thank You!!!
~Node(){ delete next; } makes it hard to delete a single node from that list. It'll delete all nodes after it too.
I suggest that the individual Nodes do not delete following Nodes:
class Node {
public:
int data;
Node* next;
Node(int d) : // colon starts the member initializer list
data(d), next(nullptr)
{
// the body of the constructor can now be empty
}
// No user-defined destructor needed here
};
Instead, delete all Nodes in the destructor of List:
~List() {
for(Node* next; head; head = next) {
next = head->next;
delete head;
}
}
Unrelated to the problem at hand. These are just suggestions:
You could make the constructor of Node a little more versatile so it's possible to provide the next Node already at construction:
class Node {
public:
int data;
Node* next;
// `nullptr` below is a default argument that will be used if the
// user of this class does not provide a second argument
Node(int d, Node* n = nullptr) :
data(d), next(n)
{}
};
This could be used in a List member function called push_front:
void push_front(int data) {
head = new Node(data, head);
if(!tail) tail = head;
}
Unrelated to that, you could make push_back a little clearer without even changing the current Node at all:
void push_back(int data) {
Node* n = new Node(data);
if(tail) tail->next = n;
else head = n;
tail = n;
}
To follow up on my comments: Throw away both your Node and List class, and actually use the language:
#include <forward_list>
#include <iostream>
int main(){
std::forward_list< int > l { 1, 2, 3, 4, 5 };
l.remove( 1 );
for ( auto & node : l )
{
std::cout << node << " ";
}
}

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.

getting a weird value using nodes in c++

I hope this question wasn't asked before. I tried searching for an answer but couldn't find any. I'm trying to learn pointers and linked lists in C++. this is my code so far
#include <iostream>
using namespace std;
struct node{
int value;
node* next;
};
node createNode(int value){
node temp;
temp.value = value;
temp. next = NULL;
return temp;
}
void add( node*& head, int value){
node temp = createNode(value);
// the problem is in this if statement
if (head->next == NULL){
head->next = &temp;
}
}
int main() {
node* head;
add(head,4);
cout<<head->next->value;
return 0;
}
if I try to grab the address of temp into the head, in my main function, the cout will print this value "1634545454" and If I move the code line "head->next = &temp;" outside of the if statement, it'll print the correct result which is 4. I don't understand why is that happening! what is that value? is the condition inside the if statement doing anything to the address, or the value of head->next?
You're declaring temp as a node (note the lack of *), i.e. a local variable. So it's automatically being freed at the end of the function.
Roughly speaking, you need to decide how you want to manage your memory. If you're going to do it all yourself, you need to use node* everywhere and remember to free your data structures when they go out of scope. But the more modern, safer approach would be to use unique_ptr<node>, which correctly captures that your node owns its next pointer. In this way, the data will be freed automatically when the time comes, but not before.
as #Silvio Mayolo mentioned you have two choices of using self managing memory or smart pointers , but as your base code was written in the self managing way ive fixed some of the pointers in your code.
the node pointer named head was not memory allocated and the temp variable most be a pointer so that the lifecycle dosent exceeds ,and if your using c++11 and above using nullptr would be better.
#include <iostream>
using namespace std;
struct node{
int value;
node* next=nullptr;
};
node* createNode(int value){
node* temp=new node;
temp->value = value;
temp->next = nullptr;
return temp;
}
void add( node* head, int value){
node* temp = createNode(value);
if (head->next == nullptr){
head->next = temp;
}
}
int main() {
node* head=new node;
add(head,4);
cout<<head->next->value;
return 0;
}
#include<iostream>
using namespace std;
struct node{
int value;
node* next=NULL; //node* next;
};
node* createNode(int value){ //node createNode(int value){
node* temp=new node; //node temp;
temp->value = value;
temp->next = NULL;
return temp;
}
void add( node* head, int value){ //void add( node*& head, int value){
node* temp = createNode(value); //node temp = createNode(value);
if (head->next == NULL){
head->next = temp; //head->next = &temp;
}
}
int main() {
node* head=new node; //node* head;
add(head,4);
cout<<head->next->value;
return 0;
}

Template Linked List | Uninitialized variable error

I'm practicing implementing a Template Class Linked List with the Node struct within the implementation of the Linked List Class. In the createNode() member function, when I initialize a pointer variable to a node struct, I get the compiler error: "Uninitialized local variable 'newNode' used"
I've found if I change the initialization to:
Node* newNode = new Node();
That it works just fine. I'm a bit confused as to why this matters if I can initialize the basic data types like int as:
int* intPtr;
Why can't I do the same with structs?? My code is below:
#include <iostream>
#include <string>
template<class T>
class LinkedList
{
private:
struct Node
{
T data;
Node* next;
};
Node* head;
Node* tail;
int size;
public:
LinkedList() : head{ nullptr }, tail{ nullptr }, size{ 0 }
{
}
Node* createNode(T data)
{
Node* newNode;
newNode->data = data;
newNode->next = nullptr;
return newNode;
}
void display()
{
Node* currentNode = head;
while (currentNode)
{
std::cout << currentNode->data << std::endl;
currentNode = currentNode->next;
}
}
void push(T data)
{
Node* newNode = createNode(data);
if (size == 0)
{
head = newNode;
tail = newNode;
}
else
{
tail->next = newNode;
tail = newNode;
}
++size;
}
};
int main()
{
LinkedList<int> list;
list.push(5);
list.push(3);
list.push(6);
list.display();
std::cin.clear();
std::cin.ignore(32767, '\n');
std::cin.get();
return 0;
}
You said:
I'm a bit confused as to why this matters if I can initialize the basic data types like int as:
int* intPtr;
That's a wrong conclusion. If you use:
int* intPtr;
*intPtr = 10;
you'll probably see the same warning/error from the compiler. The correct way to use intPtr will be to make sure it is initialized to point to a valid object before anything is assigned to it using *intPtr.
int* intPtr = new int;
*intPtr = 10;
This is similar to using
Node* newNode = new Node();
newNode->data = data;
newNode->next = nullptr;
in your code.

Simple linked list in C++

I am about to create a linked that can insert and display until now:
struct Node {
int x;
Node *next;
};
This is my initialisation function which only will be called for the first Node:
void initNode(struct Node *head, int n){
head->x = n;
head->next = NULL;
}
To add the Node, and I think the reason why my linked list isn't working correct is in this function:
void addNode(struct Node *head, int n){
struct Node *NewNode = new Node;
NewNode-> x = n;
NewNode -> next = head;
head = NewNode;
}
My main function:
int _tmain(int argc, _TCHAR* argv[])
{
struct Node *head = new Node;
initNode(head, 5);
addNode(head, 10);
addNode(head, 20);
return 0;
}
Let me run the program as I think it works. First I initialise the head Node as a Node like this:
head = [ 5 | NULL ]
Then I add a new node with n = 10 and pass head as my argument.
NewNode = [ x | next ] where next points at head. And then I change the place where head is pointing to NewNode, since NewNode is the first Node in LinkedList now.
Why isn't this working? I would appreciate any hints that could make me move in the right direction. I think LinkedList is a bit hard to understand.
When I'm printing this, it only returns 5:
This is the most simple example I can think of in this case and is not tested. Please consider that this uses some bad practices and does not go the way you normally would go with C++ (initialize lists, separation of declaration and definition, and so on). But that are topics I can't cover here.
#include <iostream>
using namespace std;
class LinkedList{
// Struct inside the class LinkedList
// This is one node which is not needed by the caller. It is just
// for internal work.
struct Node {
int x;
Node *next;
};
// public member
public:
// constructor
LinkedList(){
head = NULL; // set head to NULL
}
// destructor
~LinkedList(){
Node *next = head;
while(next) { // iterate over all elements
Node *deleteMe = next;
next = next->next; // save pointer to the next element
delete deleteMe; // delete the current entry
}
}
// This prepends a new value at the beginning of the list
void addValue(int val){
Node *n = new Node(); // create new Node
n->x = val; // set value
n->next = head; // make the node point to the next node.
// If the list is empty, this is NULL, so the end of the list --> OK
head = n; // last but not least, make the head point at the new node.
}
// returns the first element in the list and deletes the Node.
// caution, no error-checking here!
int popValue(){
Node *n = head;
int ret = n->x;
head = head->next;
delete n;
return ret;
}
// private member
private:
Node *head; // this is the private member variable. It is just a pointer to the first Node
};
int main() {
LinkedList list;
list.addValue(5);
list.addValue(10);
list.addValue(20);
cout << list.popValue() << endl;
cout << list.popValue() << endl;
cout << list.popValue() << endl;
// because there is no error checking in popValue(), the following
// is undefined behavior. Probably the program will crash, because
// there are no more values in the list.
// cout << list.popValue() << endl;
return 0;
}
I would strongly suggest you to read a little bit about C++ and Object oriented programming. A good starting point could be this: http://www.galileocomputing.de/1278?GPP=opoo
EDIT: added a pop function and some output. As you can see the program pushes 3 values 5, 10, 20 and afterwards pops them. The order is reversed afterwards because this list works in stack mode (LIFO, Last in First out)
You should take reference of a head pointer. Otherwise the pointer modification is not visible outside of the function.
void addNode(struct Node *&head, int n){
struct Node *NewNode = new Node;
NewNode-> x = n;
NewNode -> next = head;
head = NewNode;
}
I'll join the fray. It's been too long since I've written C. Besides, there's no complete examples here anyway. The OP's code is basically C, so I went ahead and made it work with GCC.
The problems were covered before; the next pointer wasn't being advanced. That was the crux of the issue.
I also took the opportunity to make a suggested edit; instead of having two funcitons to malloc, I put it in initNode() and then used initNode() to malloc both (malloc is "the C new" if you will). I changed initNode() to return a pointer.
#include <stdlib.h>
#include <stdio.h>
// required to be declared before self-referential definition
struct Node;
struct Node {
int x;
struct Node *next;
};
struct Node* initNode( int n){
struct Node *head = malloc(sizeof(struct Node));
head->x = n;
head->next = NULL;
return head;
}
void addNode(struct Node **head, int n){
struct Node *NewNode = initNode( n );
NewNode -> next = *head;
*head = NewNode;
}
int main(int argc, char* argv[])
{
struct Node* head = initNode(5);
addNode(&head,10);
addNode(&head,20);
struct Node* cur = head;
do {
printf("Node # %p : %i\n",(void*)cur, cur->x );
} while ( ( cur = cur->next ) != NULL );
}
compilation: gcc -o ll ll.c
output:
Node # 0x9e0050 : 20
Node # 0x9e0030 : 10
Node # 0x9e0010 : 5
Below is a sample linkedlist
#include <string>
#include <iostream>
using namespace std;
template<class T>
class Node
{
public:
Node();
Node(const T& item, Node<T>* ptrnext = NULL);
T value;
Node<T> * next;
};
template<class T>
Node<T>::Node()
{
value = NULL;
next = NULL;
}
template<class T>
Node<T>::Node(const T& item, Node<T>* ptrnext = NULL)
{
this->value = item;
this->next = ptrnext;
}
template<class T>
class LinkedListClass
{
private:
Node<T> * Front;
Node<T> * Rear;
int Count;
public:
LinkedListClass();
~LinkedListClass();
void InsertFront(const T Item);
void InsertRear(const T Item);
void PrintList();
};
template<class T>
LinkedListClass<T>::LinkedListClass()
{
Front = NULL;
Rear = NULL;
}
template<class T>
void LinkedListClass<T>::InsertFront(const T Item)
{
if (Front == NULL)
{
Front = new Node<T>();
Front->value = Item;
Front->next = NULL;
Rear = new Node<T>();
Rear = Front;
}
else
{
Node<T> * newNode = new Node<T>();
newNode->value = Item;
newNode->next = Front;
Front = newNode;
}
}
template<class T>
void LinkedListClass<T>::InsertRear(const T Item)
{
if (Rear == NULL)
{
Rear = new Node<T>();
Rear->value = Item;
Rear->next = NULL;
Front = new Node<T>();
Front = Rear;
}
else
{
Node<T> * newNode = new Node<T>();
newNode->value = Item;
Rear->next = newNode;
Rear = newNode;
}
}
template<class T>
void LinkedListClass<T>::PrintList()
{
Node<T> * temp = Front;
while (temp->next != NULL)
{
cout << " " << temp->value << "";
if (temp != NULL)
{
temp = (temp->next);
}
else
{
break;
}
}
}
int main()
{
LinkedListClass<int> * LList = new LinkedListClass<int>();
LList->InsertFront(40);
LList->InsertFront(30);
LList->InsertFront(20);
LList->InsertFront(10);
LList->InsertRear(50);
LList->InsertRear(60);
LList->InsertRear(70);
LList->PrintList();
}
Both functions are wrong. First of all function initNode has a confusing name. It should be named as for example initList and should not do the task of addNode. That is, it should not add a value to the list.
In fact, there is not any sense in function initNode, because the initialization of the list can be done when the head is defined:
Node *head = nullptr;
or
Node *head = NULL;
So you can exclude function initNode from your design of the list.
Also in your code there is no need to specify the elaborated type name for the structure Node that is to specify keyword struct before name Node.
Function addNode shall change the original value of head. In your function realization you change only the copy of head passed as argument to the function.
The function could look as:
void addNode(Node **head, int n)
{
Node *NewNode = new Node {n, *head};
*head = NewNode;
}
Or if your compiler does not support the new syntax of initialization then you could write
void addNode(Node **head, int n)
{
Node *NewNode = new Node;
NewNode->x = n;
NewNode->next = *head;
*head = NewNode;
}
Or instead of using a pointer to pointer you could use a reference to pointer to Node. For example,
void addNode(Node * &head, int n)
{
Node *NewNode = new Node {n, head};
head = NewNode;
}
Or you could return an updated head from the function:
Node * addNode(Node *head, int n)
{
Node *NewNode = new Node {n, head};
head = NewNode;
return head;
}
And in main write:
head = addNode(head, 5);
The addNode function needs to be able to change head. As it's written now simply changes the local variable head (a parameter).
Changing the code to
void addNode(struct Node *& head, int n){
...
}
would solve this problem because now the head parameter is passed by reference and the called function can mutate it.
head is defined inside the main as follows.
struct Node *head = new Node;
But you are changing the head in addNode() and initNode() functions only. The changes are not reflected back on the main.
Make the declaration of the head as global and do not pass it to functions.
The functions should be as follows.
void initNode(int n){
head->x = n;
head->next = NULL;
}
void addNode(int n){
struct Node *NewNode = new Node;
NewNode-> x = n;
NewNode->next = head;
head = NewNode;
}
I think that, to make sure the indeep linkage of each node in the list, the addNode method must be like this:
void addNode(struct node *head, int n) {
if (head->Next == NULL) {
struct node *NewNode = new node;
NewNode->value = n;
NewNode->Next = NULL;
head->Next = NewNode;
}
else
addNode(head->Next, n);
}
Use:
#include<iostream>
using namespace std;
struct Node
{
int num;
Node *next;
};
Node *head = NULL;
Node *tail = NULL;
void AddnodeAtbeggining(){
Node *temp = new Node;
cout << "Enter the item";
cin >> temp->num;
temp->next = NULL;
if (head == NULL)
{
head = temp;
tail = temp;
}
else
{
temp->next = head;
head = temp;
}
}
void addnodeAtend()
{
Node *temp = new Node;
cout << "Enter the item";
cin >> temp->num;
temp->next = NULL;
if (head == NULL){
head = temp;
tail = temp;
}
else{
tail->next = temp;
tail = temp;
}
}
void displayNode()
{
cout << "\nDisplay Function\n";
Node *temp = head;
for(Node *temp = head; temp != NULL; temp = temp->next)
cout << temp->num << ",";
}
void deleteNode ()
{
for (Node *temp = head; temp != NULL; temp = temp->next)
delete head;
}
int main ()
{
AddnodeAtbeggining();
addnodeAtend();
displayNode();
deleteNode();
displayNode();
}
In a code there is a mistake:
void deleteNode ()
{
for (Node * temp = head; temp! = NULL; temp = temp-> next)
delete head;
}
It is necessary so:
for (; head != NULL; )
{
Node *temp = head;
head = temp->next;
delete temp;
}
Here is my implementation.
#include <iostream>
using namespace std;
template< class T>
struct node{
T m_data;
node* m_next_node;
node(T t_data, node* t_node) :
m_data(t_data), m_next_node(t_node){}
~node(){
std::cout << "Address :" << this << " Destroyed" << std::endl;
}
};
template<class T>
class linked_list {
public:
node<T>* m_list;
linked_list(): m_list(nullptr){}
void add_node(T t_data) {
node<T>* _new_node = new node<T>(t_data, nullptr);
_new_node->m_next_node = m_list;
m_list = _new_node;
}
void populate_nodes(node<T>* t_node) {
if (t_node != nullptr) {
std::cout << "Data =" << t_node->m_data
<< ", Address =" << t_node->m_next_node
<< std::endl;
populate_nodes(t_node->m_next_node);
}
}
void delete_nodes(node<T>* t_node) {
if (t_node != nullptr) {
delete_nodes(t_node->m_next_node);
}
delete(t_node);
}
};
int main()
{
linked_list<float>* _ll = new linked_list<float>();
_ll->add_node(1.3);
_ll->add_node(5.5);
_ll->add_node(10.1);
_ll->add_node(123);
_ll->add_node(4.5);
_ll->add_node(23.6);
_ll->add_node(2);
_ll->populate_nodes(_ll->m_list);
_ll->delete_nodes(_ll->m_list);
delete(_ll);
return 0;
}
link list by using node class and linked list class
this is just an example not the complete functionality of linklist, append function and printing a linklist is explained in the code
code :
#include<iostream>
using namespace std;
Node class
class Node{
public:
int data;
Node* next=NULL;
Node(int data)
{
this->data=data;
}
};
link list class named as ll
class ll{
public:
Node* head;
ll(Node* node)
{
this->head=node;
}
void append(int data)
{
Node* temp=this->head;
while(temp->next!=NULL)
{
temp=temp->next;
}
Node* newnode= new Node(data);
// newnode->data=data;
temp->next=newnode;
}
void print_list()
{ cout<<endl<<"printing entire link list"<<endl;
Node* temp= this->head;
while(temp->next!=NULL)
{
cout<<temp->data<<endl;
temp=temp->next;
}
cout<<temp->data<<endl;;
}
};
main function
int main()
{
cout<<"hello this is an example of link list in cpp using classes"<<endl;
ll list1(new Node(1));
list1.append(2);
list1.append(3);
list1.print_list();
}
thanks ❤❤❤
screenshot https://i.stack.imgur.com/C2D9y.jpg