Barbu Vlad
Barbu Vlad

Reputation: 31

Accessing an object after calling the destructor

In the code below I call the ~destructor() explicitly. However the object is still accessible. How can I delete it(make it disappear)?

class Queue {
    public:
    node* top = NULL;//points to the top of the queue 
    //methods:
    void enqueue(int data);//adds a node to the queue
    void dequeue();
    //printing 
    void print();
    //destructor 
    ~Queue();
};

And the destructor:

Queue::~Queue() {
    //The destructor deletes all items from HEAP
    //Then sets the top to 0
    while (top != NULL)
        this->dequeue();//dequeue until there are NO more items
    top = 0;
}

In Source.cpp:

Queue q;

q.enqueue(1);
q.enqueue(2);
q.enqueue(3);
q.enqueue(4);

q.dequeue();
q.dequeue();
q.print();

q.~Queue();
q.print();//Here I need to have an ERROR!

q.enqueue(7);//Here I need to have an ERROR!
q.print();//Here I need to have an ERROR!

The output is:

4 3 7

I expect an error:

identifier "q" is undefined

Upvotes: 2

Views: 1068

Answers (2)

Edison von Myosotis
Edison von Myosotis

Reputation: 619

If you know the internals of the object you might use the object after destruction. But the destructor might have adjusted the virtual function table pointer so that the object isn't reusable any more.

Upvotes: 0

463035818_is_not_an_ai
463035818_is_not_an_ai

Reputation: 122458

Taking //Here I need to have an ERROR! literally, here is how you would do that:

{
    Queue q;

    q.enqueue(1);
    q.enqueue(2);

    q.dequeue();
    q.print();
}
q.print();        // THIS WILL PRODUCE AN ERROR

You seem to have a misunderstanding on lifetime of stack allocated objects. Stack objects are automatically destroyed when they go out of scope. In the example the scope of q ends with }.

Calling the destructor yourself is almost always wrong (I encountered exactly one single case where it was ok to call the destructor explicitly). Why? Consider this:

{
    Queue q;
    q.~Queue();   // DONT DO THIS !
}

You called the destructor but when it goes out of scope it gets destroyed again and you will get nasty runtime errors.

What you do in your code:

Queue q;
q.~Queue();
q.print();

is undefined behaviour!

Also note that calling the destructor is not all that happens when an object is deleted. When an stack allocated object is deleted, first its destructor is called and then the allocated memory is freed. Usually you do not want to interfer with this process and luckily you rarely have to.

How can I delete it(make it disappear)?

You cannot make it "disappear". When an object is destroyed the bits and bytes in memory are not erased. That would be awfully inefficient. Actually I think C's free has a much better and less confusing name. Memory is freed to be used later, it is not wiped out such that it would be impossible to read what was there before.

For further reading I refer you to this exahaustive answer to a slightly different but related question: Can a local variable's memory be accessed outside its scope?

Also, I suggest you to read about RAII which relies on destructors being called automatically.

TL;DR: If you want to clear the Queue then write:

q.clear();
q.print(); // prints an empty queue!

Don't ever call the destructor of a stack allocated object! It will be called automatically.

Upvotes: 5

Related Questions