if deleting top pointer deletes all pointers - c++

I have a doubt. Let’s say that I have implemented a stack in a way similar to a linked list, like this (there are just a push and a print function)
#include <iostream>
template <class T>
struct node{
T data;
node<T> *down;
};
template <class T>
class mystack{
public:
node<T> *top = new node<T>;
mystack(){top = nullptr; std::cout << "CONSTRUCTION!" << std::endl;}
~mystack(){delete top; std::cout << "DESTRUCTION!" << std::endl;}
void push(T elem){
node<T> *new_node = new node<T>;
new_node -> data = elem;
if (!top){
new_node -> down = top;
top = new_node;
return;
}
else{
node<T> *temp = top;
new_node -> down = temp;
top = new_node;
return;
}
}
void print_stack(){
node<T> *temp = top;
while(temp){
std::cout << temp -> data << std::endl;
temp = temp -> down;
}
}
};
int main(){
mystack<int> st;
st.push(20);
st.push(200);
st.push(2000);
st.print_stack();
}
my question is: does deleting the top pointer delete all the other pointers or just the first one and the other are still there sitting (hence this code is very bad)?.
Plus, would you rather use a smart pointer to do this kind of stuff? Thank you for your time.

Your single delete is insufficient. You need something like:
~mystack()
{
while(top != nullptr)
{
node<T> *curr = top;
top = top->down;
delete curr;
}
std::cout << "DESTRUCTION!" << std::endl;
}
That way, you delete every element in your container.

Related

How to get below linked list with friend operator to working?

I am trying to execute linked list with the below code.But I am unable to figure out the mistake in it.
I got the concept of it but I am failing to implement the same.
Any help is highly appreciated.
#include <iostream>
using namespace std;
struct Node {
int data;
Node *next;
Node(int j) : data(j), next(nullptr) {}
friend ostream &operator<<(ostream &os, const Node &n) {
cout << "Node\n"
<< "\tdata: " << n.data << "\n";
return os;
}
};
void addElement(Node **head, int data){
Node *temp = nullptr;
temp->data = data;
temp->next=nullptr;
Node *cur = *head;
while(cur) {
if(cur->next == nullptr) {
cur->next = temp;
return;
}
cur = cur->next;
}
};
void printList(const Node *head){
const Node *list = head;
while(list) {
cout << list;
list = list->next;
}
cout << endl;
cout << endl;
};
void deleteList(Node *head){
Node *delNode =nullptr;
while(head) {
delNode = head;
head = delNode->next;
delete delNode;
}};
int main() {
Node *list = nullptr;
addElement(&list, 1);
addElement(&list, 2);
printList(list);
deleteList(list);
return 0;
}
after compiling I am getting no error and no output.So I am unable to figure what is going wrong or else my implementation of which is not right!
Here an error straightaway
void addElement(Node **head, int data){
Node *temp = nullptr;
temp->data = data;
temp is null, but you dereference it. It's an error to dereference a null pointer.
I guess you meant this
void addElement(Node **head, int data) {
Node *temp = new Node(data);
which allocates a new Node, initialises it with data and makes temp point to the newly allocated Node.

singly linked list c++ constructor, destructor and printing out

I am a beginner learning c++, and currently making a singly linked list. I have faced some problems and I thought for a very long time, searched a lot but still do not have an answer for this code so I am begging for some help..
So this is my linked.h
template <class T>
class Node {
public:
T data;
Node<T>* next;
};
template <class T>
class List {
private:
Node<T> *head;
public:
List() : head(NULL) {};
~List() {
Node<T>* ptr, tmp;
for(ptr = head->next; ptr == NULL; ptr = head->next) {
delete ptr;
}
}
List(T* arr, int n_nodes) {
head = NULL;
Node<T> *tmp = head;
for(int i = 0; i < n_nodes; i++) {
Node<T>* node = new Node<T>;
node->data = arr[i];
if(head == NULL) {
head->next = node;
tmp = node;
}
else {
tmp->next = node;
node->next = NULL;
tmp = node;
}
}
}
friend std::ostream& operator<<(std::ostream& out, List<T>& rhs) {
Node<T>* cur = rhs.head;
out << cur;
while(cur != NULL) {
if(cur->next != NULL) {
out << cur->data << ", ";
cur = cur->next;
}
else
out << cur->data << " ";
}
return out;
}
};
and this is my main.cc file.
#include <iostream>
#include "linked.h"
int main() {
int array[5] = {12, 7, 9, 21, 13};
List<int> li(array, 5);
std::cout << li;
return 0;
}
I keep on getting segmentation fault when running the constructor and I don't get why. Where am I making a mistake? Any help would be appreciated!
You could cover the issue with a pointer to pointer:
List(T* arr, int n_nodes)
{
Node<T>** tmp = &head; // tmp *pointing* to uninitialized(!) head pointer
for(int i = 0; i < n_nodes; i++)
{
Node<T>* node = new Node<T>();
node->data = arr[i];
// now the trick:
*tmp = node; // !!!
// you now have assigned the new node to whatever pointer
// the tmp pointer points to - which initially is - guess - head...
// but we now need to advance!
tmp = &node->next;
}
// tmp now points to latestly created node's next pointer
// (or still head, if no nodes where created because of n_nodes == 0)
// be aware that this one still is not initialized! so:
*tmp = nullptr;
}
Your destructor necessarily fails, too:
Node<T>* ptr, tmp;
for(ptr = head->next; ptr == NULL; ptr = head->next)
{
delete ptr; // you delete ptr, but advancing (ptr = head->next)
// is done AFTERWARDS, so you'd access already deleted memory
// undefined behaviour
}
Additionally, you don't delete the head node! And if head is nullptr, you again have undefined behaviour.
Try it this way:
while(head)
{
Node<T>* tmp = head; // need a copy of pointer
head = head->next; // need to advance BEFORE deleting
delete tmp; // now can delete safely
}

c++ single linked list segmentation fault t

I am trying to write a code making a single linked list. I want to put all my array elements into each node and link them. But when I run my code I keep getting the segmentation fault error. I do not get why I am getting this error.
Can anybody help?? Thanks!!
linked_list_main.cc
#include <iostream>
#include "linked_list.h"
int main() {
int array[5];
List<int> list(array, 5);
std::cout << list;
return 0;
}
template <class T>
class Node {
public:
T data;
Node<T>* next;
};
This is my linked_list.h file.
class List {
private:
Node<T> *head;
public:
List() : head(NULL) {};
~List() {
Node<T>* ptr;
for(ptr = head; ptr == NULL; ptr = head->next)
delete ptr;
}
List(T* arr, int n_nodes){
Node<T>* tmp = head;
for(int i = 0; i < n_nodes; i++ ) {
Node<T>* node = new Node<T>;
node->data = arr[i];
if(tmp != NULL) {
node->next = tmp;
tmp = node;
}
}
}
friend std::ostream& operator<<(std::ostream& out, List<T>& rhs) {
Node<T>* cur = rhs.head;
while(cur != NULL) {
if(cur->next == NULL)
out << cur->data << " ";
else
out << cur->data << ", ";
cur = cur->next;
}
}
};
You need to change this
List(T* arr, int n_nodes){
Node<T>* tmp = head;
...
}
to this
List(T* arr, int n_nodes){
Node<T>* tmp = NULL;
...
head = tmp;
}
Pointers are tricky, learn to use a debugger. Will be the best hour you've ever spent when learning how to program.

C++ Linked List confusion

I've been stuck trying to figure out how I can implement a NODE based link list that can hold anything (via templates).
I've got the Node class ready and working(tested with my Stack class).
I was curious where I could be going wrong when making the function called insertAtIndex where I take in the data to store and the index at where it should be stored.
My Node class
template <class T>
class Node
{
public:
T *data; //the object information
Node<T> *next; //pointer to the next node element
Node()
{
next = 0;
data = 0;
}
};
Here's my Linked List class so far
template <class T>
class LinkedList
{
private:
Node<T> *head;
int count;
public:
LinkedList()
{
head = 0;
count = 0;
}
int getCount()
{
return count;
}
void insertAtIndex(T* dat, int index)
{
Node<T> * temp = new Node<T>(dat);
if(index == 0)
{
temp = head;
temp->data = dat;
temp->next = temp->next;
temp->next = temp;
delete temp;
count++;
}
else if(index <= count)
{
Node<T> *cursor = new Node<T>();
for(int i = 0; i < index - 1; i++)
{
cursor = cursor->next;
}
Node<T> * temp = new Node<T>();
temp->data = dat;
temp->next = cursor->next;
cursor->next = temp;
count++;
}
}
void Print()
{
// Temp pointer
Node<T> *tmp = head;
// No nodes
if ( tmp == NULL ) {
cout << "EMPTY" << endl;
return;
}
// One node in the list
if ( tmp->next == NULL ) {
cout << *tmp->data;
cout << " --> ";
cout << "NULL" << endl;
}
else
{
// Parse and print the list
do
{
cout << *tmp->data;
cout << " --> ";
tmp = tmp->next;
}
while ( tmp != NULL );
cout << "NULL" << endl;
}
}
};
You should add Node(T*) constructor to your Node class:
template <class T>
class Node
{
public:
T *data; //the object information
Node<T> *next; //pointer to the next node element
Node()
{
next = 0;
data = 0;
}
Node(T* newData) { // <<---------- Here it is
next = 0;
data = newData;
}
};
You need to rethink how you are adding nodes to the list. Here is your code with comments on what it is actually doing.
Node<T> * temp = new Node<T>(dat); // Create new node, good
if(index == 0)
{
temp = head; // Throw away pointer to new node, bad. temp is now head.
temp->data = dat; // Overwrite head's data, bad
temp->next = temp->next; // Set a variable to itself, does nothing.
temp->next = temp; // Change head's next to point to itself, bad
delete temp; // delete the head node, bad
count++;
}
What you actually want to do is:
Create a new node with the right data (you already do this)
If you are putting it at the start of the list:
Point the new node's next pointer to head
Change head to point to the new node
That's all - don't delete anything.
Once you have that working, move on to the more complicated part of adding a node to the middle or the list (your else part).
A debugger (or at least output statements) is essential for learning where your code is going wrong. You can look at the state of your variables at each point.
You might want to consider a base node class that only has a next pointer as a member, then an inherited class that adds a template data member. Common list functions could be used for the base class.

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