I know the logic in the code given below is wrong but I have doubts about what happens when we delete p having the address of the next node.
What will the destructor do? will it go to all the node make them null until the Next in node p don't become null
Also tell me what destructors do to memory. I have read many articles on destructor, deallocation ,delete and free but I am still confused. Main confusion is in deallocation and destructor.
class Node {
public:
int data;
Node * next;
Node(int data){
this -> data = data;
this -> next = NULL;
}
~Node() {
if(next) {
delete next;
}
}
};
void deleteAlternateNodes(Node *head) {
//Write your code here
Node *p =head;
Node *q =NULL;
if(p->next == NULL)
{
return;
}
while(p!=NULL)
{
q=p;
p=p->next;
q->next = p->next;
delete p;
p = q->next;
}
}
In this statement of the operator delete
delete p;
all nodes that follow the node pointed to by the pointer p
(due to the data member next
) will be deleted.
So the function deleteAlternateNodes
invokes undefined behavior because all nodes pointed to by the expression q->next
that is assigned like
q->next = p->next;
will be deleted due to this statement
delete p;
So this statement
p = q->next;
sets the pointer p
to an invalid pointer.
Here is a demonstrative program
#include <iostream>
class Node
{
public:
int data;
Node * next;
Node(int data)
{
this -> data = data;
this -> next = NULL;
}
~Node()
{
std::cout << "The destructor is called for node with data equal to "
<< data << '\n';
if(next)
{
delete next;
}
}
};
void display( const Node *head )
{
for ( ; head; head = head->next )
{
std::cout << head->data << " -> ";
}
std::cout << "null\n";
}
int main()
{
Node *head = new Node( 1 );
Node *current = head;
current->next = new Node( 2 );
current = current->next;
current->next = new Node( 3 );
display( head );
delete head;
return 0;
}
The program output is
1 -> 2 -> 3 -> null
The destructor is called for node with data equal to 1
The destructor is called for node with data equal to 2
The destructor is called for node with data equal to 3
In fact the if statement in the destructor is redundant
if(next)
{
delete next;
}
You may just write
delete next;
without the if statement because for a null pointer the destructor will not be called. For example
~Node()
{
std::cout << "The destructor is called for node with data equal to "
<< data << '\n';
delete next;
}
or
~Node()
{
delete next;
}