Accessing an object after calling the destructor - c++

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

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.

Related

Deleting an object declared on the stack

I wanted to know what happens if we delete an object declared on the stack, two times. In order to test this I've written this simple program:
#include <iostream>
using namespace std;
class A {
public:
A() {}
virtual ~A() {
cout << "test" << endl;
}
};
int main()
{
A a;
a.~A();
}
I was actually expecting a segmentation fault, as I'm deleting A once explicitly in the code, and it will be deleted again when it goes out of scope, however suprisingly the program produces the following ouput:
"test"
"test"
Can anybody explain why this code is working??
There are three reasons:
The destructor does not deallocate the object, it performs whatever cleanup operation you find useful (and by default, nothing). It is implicitly called before a variable goes out of scope or is explicitly deleted, but you are free to call it as well.
Deallocation usually does not cause memory to cease existing nor to be inaccessible. It is rather marked as reusable. (Anyway, double deallocation should raise a memory management error condition.)
Last but not least, an object allocated on the stack is not deallocated (when you exit the function, the stack pointer moves to the previous frame, leaving the stack unchanged).
Your program has undefined behaviour, so it may just as easily have segfaulted, or stolen my car, or gone into space to start an exciting new colony of lesbian parrots.
But, in practice, the behaviour you've witnessed can be explained. Calling the destructor does not "delete" an object; it just calls the destructor. A destructor call is one part of object deletion; yours just prints to standard output, so there's really nothing to trigger a memory access violation here.
More generally, "expecting a segmentation fault" is always folly.
However, if you'd actually attempted to delete the object with delete, I would be surprised if your program didn't crash at runtime.
You called the destructor of a. This does not delete the variable, it just call the destructor function. The variable will be remove from the stack at the exit of the function.
As the name says, a is a "variable with automatic lifetime" which means you can't end it's lifetime prematurely yourself. It is bound to the scope it was created in. You're just manually calling the destructor which is just another method that prints something. Then it's called again automatically by the runtime on actual destruction and end of lifetime. You can somewhat control the lifetime of an automatically managed object by defining the scope of it:
int main()
{
{
A a;
} // 'a' is destroyed here.
} // instead of here.

Why does destructor get called twice in here?

#include <iostream>
struct ABC{
int A;
ABC(int i = 1) : A(i) {}
~ABC() {
std::cout << A << std::endl;
}
void destruct() {
delete this;
}
};
int main() {
ABC A1(2);
A1.destruct();
return 0;
}
Output:
2
2
I have this code in which I'm trying to manually delete structure variable. Doing so, I realized the destructor gets called twice here. Why is this happening? Why isn't it getting deleted when destruct() is called?
The delete this call causes undefined behaviour, which means that anything at all can happen.
delete may only be used for objects created by new.
For automatic objects with a non-trivial destructor (e.g. your A1), it is not possible to "destroy them early" unless you also create another ABC in the same place before the scope ends. In other words you can't "turn off" the destruction process that occurs when the scope ends.
Why isn't [my object] getting deleted when destruct() is called?
When an object gets destructed in C++, it does not mean that the object disappears. It means that the clean-up code from the destructor gets executed, and that any access to the object's members from that point on is invalid.
When you call destruct() you try to free object's memory by calling delete. This is undefined behavior in itself, because you have not allocated the object with new. This call causes the first printout.
However, since your object is in automatic memory, C++ is required to call its destructor when the object gets out of scope. This is the call that causes the second printout.
Note: You can fix your code by allocating A1 in dynamic memory:
int main() {
ABC *A1 = new ABC(2);
A1->destruct();
return 0;
}
Now you get a single printout (demo). However, the practice of hiding delete in a member function is questionable.
This is RAII working plus you committing suicide on an object. Calling the destructor on an object is almost always wrong! And calling the destructor twice is always wrong, as it invokes undefined behaviour.
You have to understand that C++ is handling memory for you, if you just let it:
struct Foo{};
int main() {
Foo f; // automatic storage, gets destroyed
// when object gets out of scope
Foo* g = new Foo(); // heap allocated
delete g; // only here you have to delete
}
Just remember: Do not delete anything that you did not create via new (thanks to Mike Vine for the comment). And do not use (naked) heap allocation unless you need to.
Two points to consider here :-
1) Destructor for stack objects will always be called when they go out of scope. So no need to worry for their deallocation.
2) You cannot & should not use delete on the object allocated on stack. In general, you should not use delete this as long as you are not sure that this will be executed only as a consequence of deleting heap objects and after that you are not referring to that object.

How do you define a deconstructor in c++?

Just started learning C++ and I'm confused on how to program a deconstructor. So far I understand that a deconstructor is called whenever an object is destroyed, which from my understanding is when the program ends and C++ automatically destroys all objects. Does this just mean that I should just re-intialize all variables back to what they originally were?
So is this what I should have:
/*In the Header file*/
List();
~List();
//Other function prototypes go here
/*In the Implementation file*/
List::List()
{
head = NULL;
tail = NULL;
count = 1;
}
List::~List
{
head = NULL;
tail = NULL;
count = 1;
}
//Other function bodies go here
No. The destructor is for deallocating/cleaning up any resources that the object might be using. For instance file handles need to be closed, UI resources need to be released back to the system, memory that you have newed needs to be deleteed.
In your example count seems like an int, so you don't need to do anything for that as the memory for that is a part of the object being destroyed, but if you have allocated memory for your list you will have to deallocated it in the destructor. Depending on how you have constructed the list you might want to iterate through the list and deallocate each node.
To clear up one misconception, the destructor is called any time an object goes out of scope (a local variable hits the end of the code block in which it was created). If an object was created in global scope (outside of a function) it will be destroyed at program exit. Think of this as a big set of braces around the whole program.
void function(object a)
{
object b;
int x = 0;
while (x < 10)
{
object c;
// La la la Doing stuff.
} // c destroyed here. It will be created and destroyed for each run through the loop
a = b;
} //b destroyed here
// a also destroyed here, so watch out passing things into functions if you want them
// back changed.
or when it is manually destroyed with the delete command
object * d = new object();
// la la la doing stuff
delete d;
Since d was manually created, it must be manually destroyed. Watch out C# and Java people.
What do you need to do in a destructor?
Put everything away. Don't waste your time setting values back to their defaults. They won't be around long enough to appreciate the gesture. But if you opened a file, and still have it open, close it. If you newed other objects, delete them. If you have a mutex locked, unlock it. If you are managing threads, you probably want to notify the threads and wait for them to finish before finishing. But do it with a time-out so you don't hang on a stuck thread.
While we're on the topic, read this: What is The Rule of Three?
Put simply The Rule of Three means if you have a destructor, a copy constructor or an assignment operator (operator=), you almost certainly require all three. A lot of time you'll see people getting odd memory errors because they didn't obey the Rule of Three. Don't be that guy.
When you have The Rule of Three down, go looking for the Rule of Five.
How this applies to the OP:
List::~List
{
head = NULL; //very probably need to delete this pointer
tail = NULL; //and possibly this one
count = 1; // don't need this at all
}
So it should probably look like:
List::~List
{
if (head != NULL)
{
delete head; // This should start a chain reaction deleting all of the linked
// items in the list, ensuring that they have all been freed
}
}
In addition, the OP should have a copy constructor and an assignment operator that make sure that when the List is deleted it doesn't also obliterate the data of any copies of the list.
It is called destructor not deconstructor
A destructor code is generally defines how you may end the life of an instance of a class.
Usually this will include memory deallocation or freeing as well as resource freeing 'closing a file handle', unlocking a synchroniser, it might also include more complicated stuff like interrupting a thread to end it's life if this thread life cycle is inside the class.. it might have more than that like notifying about the destruction of a class to whomever have assigned for a notification .. there is a lot of code that might be required when you end an instance of a class without a destructor the encapsulation of OOP would have suffered
Last note in c++ the new, and delete reserved words are memory allocators that use the constructor/destructor of an instance of an object
I hope it is clear enough

How to delete an object (class) through destructor method

I'm wonder to know is it possible to delete an object through destructor method?
Constructor and destructor of my class:
class cal
{
public:
cal()
{
days = 0;
day = 1;
month = 1;
year = 1300;
leap = true;
};
~cal()
{
delete this;
}
}*calendar = new cal;
How can I delete this pointer through class?
P.S
I forgot to write the following code
cal *calandar = new cal[];
I want to use it in heap not stack
I want to use this class (objects) frequently (many of that object) imagine how many time should I write delete and it make hard understanding, troubleshooting and tracing codes I want them to been destroyed automatically (in heap)
I used following code in my class when I exec "delete[] calendar" it reduce my rams occupied (amount of ram that is used) does it work properly (destroy all objects) by exiting program? Because I use GNU/Linus and it destructs all objects with or without that lines I'm concern about leaking in windows
void DisposeObject() { delete this; }
No. By the time the destructor is called, the object is already being destroyed, so delete this is not valid.
The behaviour is undefined, but most likely it will call the destructor recursively, leading to a stack overflow.
You can write the code like this:
class cal
{
public:
cal()
{
};
~cal()
{
}
void DisposeObject()
{
delete this;
}
}
And it will call your destructor.
You should not call delete this from your destructor since it will call the destructor recursively, possibly leading to a stack overflow. Anyway, the code you wrote suffers from undefined behavior.
Refer to this question for in-depth discussion: Is delete this allowed?
I`m wonder to know is it possible to delete an object through destructor method
Even supposing this was valid - The problem is that nothing would ever call the destructor, so this would never have an effect. The destructor is called when the calling code deletes the object, which in turn can delete any internal objects as needed.
In your case, it doesn't look like you need to do anything in your destructor, however, as you don't have any resources being allocated that need to be explicitly deleted (at least in what you're showing).

How do I delete memory after manually invoking destructor?

I was reading this question Does calling a destructor explicitly destroy an object completely? where this situation comes up in code.
Object* aWidget = new Widget(); //allocate and construct
aWidget->~Object(); //destroy and DON'T deallocate
From the answers, I undrestand that the memory region is in fact not deallocated in this situation. My question is (more out of curiosity than anything):
How can I delete the memory pointed to by aWidget after the two lines of code above have executed? I would assume calling delete aWidget; would fail because it would try to run the destructor on an already-destructed object. Could you call free(aWidget) or something like that instead to just target the memory?
free would, factually speaking, be my best guess. However I don't think you can do anything without invoking UB. How did you arrive at a requirement to invoke the destructor like that?
Calling free on an object allocated with new is undefined behavior.
I suggest you keep it simple, and call delete.
However, if you want to do this, you can, in some cases, call delete even if you previously called the destructor explicitly. If you call it explicitly, you can view it as a function. The memory isn't freed, so I'm guessing setting member pointers to NULL after you destroy them would be enough to prevent you from running into any trouble. (because calling delete on a NULL pointer is a no-op).
For example, the following should be ok:
class A
{
public:
int * x;
A()
{
x = new int[10];
}
~A()
{
delete[] x;
x = NULL;
}
};
int main()
{
A* a = new A;
a->~A();
delete a;
return 0;
}