Why do we require Node* x = new Node() instead of Node x; - c++

When I create a Node for Linked List, Stack, Queue, Trees, etc.
I have to create the NODE using
Node* x = new Node()
But instead, we can create the object for the Linked List, etc. using
LinkedList x;
for
class Node {
int data;
Node* next;
};
class LinkedList {
Node* head = NULL;
int size = 0;
bool push();
int pop();
};

Related

why cannot we initialize a node without using a pointer?

I have recently started learning data structure and as a beginner, I have a query while implementing linked list nodes, why do we have to initialize node using a pointer only?
class node{
public:
int data;
node* next;
node(int val){
data = val;
next = NULL;
}
};
int main(){
node* head = NULL;
node head = NULL; // this throws an error which i cannot understand
}
Actually you can initialize the node by value. If you want to initialize a node with value, according to your constructor node(int val), you have to code like below:
class node{
public:
int data;
node* next;
explicit node(int val){
data = val;
next = NULL;
}
};
int main(){
int value = 777;
//node* head = NULL; // Initialize head pointers to null
node head(value); // By your constructor definition
}
EDIT: By the way, marking a constructor as explicit is a very good habit to have, as it prevents unexpected conversion, as Duthomhas commented.

Segmentation fault in C++ in printing linked list elements

please help. I am getting segmentation fault when i try to print elements in this linked list.
i first declare a class and the function to insert and display the elements of the list are its functions.
code:
#include <iostream>
using namespace std;
struct node{
int data;
node *next;
};
class ll{
node *head,*tail;
public:
void push(int x){
node *temp = new node;
temp->data = x;
temp->next = NULL;
if(head == NULL){
head = temp;
tail= temp;
}
else{
tail->next = temp;
tail= temp;
}
}
void show(){
node *n = head;
while(n!=NULL){
cout<<n->data<<"\n";
n = n->next;
}
}
};
int main()
{
ll a;
a.push(1);
a.push(2);
a.show();
return 0;
}
Neither the data member head nor the data member tail are initialized by nullptr. So the program has undefined behavior.
You could write in the class definition
class ll{
node *head = nullptr, *tail = nullptr;
//...
Bear in mind the structure node should be member of the class ll. For example
class ll{
struct node{
int data;
node *next;
} *head = nullptr,*tail = nullptr;
public:
void push( int x ){
node *temp = new node { x, nullptr };
if( head == NULL ){
head = tail = temp;
}
else {
tail = tail->next = temp;
}
}
//...
Instead of initializing data members in the class definition you coudl initialize them in the default constructor like for example
class ll{
struct node{
int data;
node *next;
} *head,*tail;
public:
ll() : head( nullptr ), tail( nullptr ) {}
// ...
Also you need at least to define the destructor and either explicitly define the copy constructor and copy assignment constructor or define them as deleted. For example
class ll{
struct node{
int data;
node *next;
} *head,*tail;
public:
ll() : head( nullptr ), tail( nullptr ) {}
~ll() { /* must be defined */ }
ll( const LL & ) = delete;
ll & operator =( const ll & ) = delete;
// ...
The problem is that you don't set head to NULL when you list is created. Same issue applies to tail. This is a job for the constructor
class ll {
node *head,*tail;
public:
ll() { head = tail = NULL; }
void push(int x) {
...

Different type of Node created

On geeks for geeks I saw a different way to create the Node for linked list.
struct Node{
int data;
Node* next;
Node(int x){
data = x;
next = NULL;
}
}
Can someone please explain me how that node is defined.
struct Node {
int data;
Node *next;
Node(int x) : data(x), next(NULL) {}
};
This is just a way to define structure with constructor in C++
You can use them simply like this
Node *node = new Node(4);

Copy constructor for List class without using any methods in implementation

I was working for writing a copy constructor for List class with requirement as not to use any other methods in implementation.
The class fragment is as follows :
class List {
private:
struct Node {
NodeData *data;
Node *next;
};
Node *head;
};
The requirement is to write copy constructor for this class and do not use any other methods in implementation except that we may use copy constructor for NodeData class
I have written the copy constructor as follows:
list::list(const list &t){
Node* q;
q=new Node;
while (p!=NULL){
q->x= p->x;}
}
This is not working, please help in how to write the copy constructor as required.
I disagree with the commentors that this is a moronic exercise, actually its interesting to try and do this. The following should give you an idea on what to try: http://ideone.com/DdC7bN
class List {
private:
struct Node {
int data; // simplification
Node *next;
Node(int d) {
data = d;
next = NULL;
}
};
protected:
Node *head;
Node *tail;
public:
List(int d) : head(new Node(d)), tail(head) {}
void append(int d) {
Node* n = new Node(d);
tail->next = n;
tail = n;
}
List(const List& rhs) {
if (head) delete head;
head=new Node(rhs.head->data);
Node* lhsCurrent = head;
Node* rhsCurrent = rhs.head->next;
do {
lhsCurrent->next = new Node(rhsCurrent->data);
rhsCurrent = rhsCurrent->next;
lhsCurrent = lhsCurrent->next;
} while (rhsCurrent!=NULL);
tail = lhsCurrent;
}
};
int main() {
List first(5);
first.append(6);
List second(first);
return 0;
}

Linked List destructor in C++: should I delete?

I've start implementing some data structures in C++, starting from Linked Lists.
Coming from a Java background, I'm still wrapping my head around pointers and objects lifespans.
LinkedList:
struct Node
{
int data;
Node *next;
};
class LinkedList
{
private:
Node *head;
Node *tail;
int length;
public:
LinkedList();
~LinkedList();
void addToHead(Node &newHead);
void popHead();
void printList();
};
and then I've implemented it like this:
LinkedList::LinkedList()
{
head = NULL;
tail = NULL;
length = 0;
}
LinkedList::~LinkedList(){}
void LinkedList::addToHead(Node& newHead)
{
newHead.next = head;
head = &newHead;
length++;
}
void LinkedList::popHead()
{
Node *currHead = head;
head = head->next;
length--;
}
void LinkedList::printList()
{
Node *curr = head;
while(curr)
{
curr = curr->next;
}
}
Lastly there's a simple main:
int main()
{
LinkedList list;
Node n1 = {3};
Node n2 = {4};
Node n3 = {5};
list.addToHead(n1);
list.addToHead(n2);
list.addToHead(n3);
list.printList();
list.popHead();
list.printList();
return 0;
}
This a rather naive implementation, and I was wondering if I had to provide a proper destructor which deletes the Node* pointers upon iteration.
Whenever I've tried to add it, the program results in a memory error, and I was thinking that the memory being allocated is being also deallocated at the end of the main, since all the Node*s live there.
Should I fix my destructor? Should I change the whole interface?
Thanks in advance!
Although there are no memory leaks in your code as it stands, I think you should change your interface.
Your linked list isn't doing what you probably think its doing - taking ownership of its contents. A linked list that doesn't own its contents is a strange beast and probably something you did not intend.
One easy way to make it take ownership is to change your design to use std::unique_ptr instead of raw pointers. Your addToHead function would then be change to take std::unique_ptr r-value references pointers (or simply raw pointers that create new std::unique_ptr internally if that's too advanced)
Here is your implementation changed to use std::unique_ptr. Its a bit rough-and-ready, but should get you on your way:
#include <memory>
struct Node
{
Node(int i) : data(i)
{}
int data;
std::unique_ptr<Node> next;
};
class LinkedList
{
private:
std::unique_ptr<Node> head;
Node *tail;
int length;
public:
LinkedList();
~LinkedList();
void addToHead(std::unique_ptr<Node>&& newHead);
void popHead();
void printList();
};
LinkedList::LinkedList()
{
head = NULL;
tail = NULL;
length = 0;
}
LinkedList::~LinkedList(){}
void LinkedList::addToHead(std::unique_ptr<Node>&& newHead)
{
newHead->next = std::move(head);
head = std::move(newHead);
length++;
}
void LinkedList::popHead()
{
head = std::move(head->next);
length--;
}
void LinkedList::printList()
{
auto* curr = head.get();
while(curr)
{
curr = curr->next.get();
}
}
int main()
{
LinkedList list;
list.addToHead(std::make_unique<Node>(3));
list.addToHead(std::make_unique<Node>(4));
list.addToHead(std::make_unique<Node>(5));
list.printList();
list.popHead();
list.printList();
return 0;
}