Deleting an object declared on the stack - c++

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.

Related

C++ member array destructor [duplicate]

I have a simple C++ code, but I don't know how to use the destructor:
class date {
public:
int day;
date(int m)
{
day =m;
}
~date(){
cout << "I wish you have entered the year \n" << day;
}
};
int main()
{
date ob2(12);
ob2.~date();
cout << ob2.day;
return 0;
}
The question that I have is, what should I write in my destructor code, that after calling the destructor, it will delete the day variable?
Rarely do you ever need to call the destructor explicitly. Instead, the destructor is called when an object is destroyed.
For an object like ob2 that is a local variable, it is destroyed when it goes out of scope:
int main()
{
date ob2(12);
} // ob2.~date() is called here, automatically!
If you dynamically allocate an object using new, its destructor is called when the object is destroyed using delete. If you have a static object, its destructor is called when the program terminates (if the program terminates normally).
Unless you create something dynamically using new, you don't need to do anything explicit to clean it up (so, for example, when ob2 is destroyed, all of its member variables, including day, are destroyed). If you create something dynamically, you need to ensure it gets destroyed when you are done with it; the best practice is to use what is called a "smart pointer" to ensure this cleanup is handled automatically.
You do not need to call the destructor explicitly. This is done automatically at the end of the scope of the object ob2, i.e. at the end of the main function.
Furthermore, since the object has automatic storage, its storage doesn’t have to be deleted. This, too, is done automatically at the end of the function.
Calling destructors manually is almost never needed (only in low-level library code) and deleting memory manually is only needed (and only a valid operation) when the memory was previously acquired using new (when you’re working with pointers).
Since manual memory management is prone to leaks, modern C++ code tries not to use new and delete explicitly at all. When it’s really necessary to use new, then a so-called “smart pointer” is used instead of a regular pointer.
You should not call your destructor explicitly.
When you create your object on the stack (like you did) all you need is:
int main()
{
date ob2(12);
// ob2.day holds 12
return 0; // ob2's destructor will get called here, after which it's memory is freed
}
When you create your object on the heap, you kinda need to delete your class before its destructor is called and memory is freed:
int main()
{
date* ob2 = new date(12);
// ob2->day holds 12
delete ob2; // ob2's destructor will get called here, after which it's memory is freed
return 0; // ob2 is invalid at this point.
}
(Failing to call delete on this last example will result in memory loss.)
Both ways have their advantages and disadvantages. The stack way is VERY fast with allocating the memory the object will occupy and you do not need to explicitly delete it, but the stack has limited space and you cannot move those objects around easily, fast and cleanly.
The heap is the preferred way of doing it, but when it comes to performance it is slow to allocate and you have to deal with pointers. But you have much more flexibility with what you do with your object, it's way faster to work with pointers further and you have more control over the object's lifetime.
Only in very specific circumstances you need to call the destructor directly. By default the destructor will be called by the system when you create a variable of automatic storage and it falls out of scope or when a an object dynamically allocated with new is destroyed with delete.
struct test {
test( int value ) : value( value ) {}
~test() { std::cout << "~test: " << value << std::endl; }
int value;
};
int main()
{
test t(1);
test *d = new t(2);
delete d; // prints: ~test: 2
} // prints: ~test: 1 (t falls out of scope)
For completeness, (this should not be used in general) the syntax to call the destructor is similar to a method. After the destructor is run, the memory is no longer an object of that type (should be handled as raw memory):
int main()
{
test t( 1 );
t.~test(); // prints: ~test: 1
// after this instruction 't' is no longer a 'test' object
new (&t) test(2); // recreate a new test object in place
} // test falls out of scope, prints: ~test: 2
Note: after calling the destructor on t, that memory location is no longer a test, that is the reason for recreation of the object by means of the placement new.
In this case your destructor does not need to delete the day variable.
You only need to call delete on memory that you have allocated with new.
Here's how your code would look if you were using new and delete to trigger invoking the destructor
class date {
public: int* day;
date(int m) {
day = new int;
*day = m;
}
~date(){
delete day;
cout << "now the destructor get's called explicitly";
}
};
int main() {
date *ob2 = new date(12);
delete ob2;
return 0;
}
Even though the destructor seems like something you need to call to get rid of or "destroy" your object when you are done using it, you aren't supposed to use it that way.
The destructor is something that is automatically called when your object goes out of scope, that is, when the computer leaves the "curly braces" that you instantiated your object in. In this case, when you leave main(). You don't want to call it yourself.
You may be confused by undefined behavior here. The C++ standard has no rules as to what happens if you use an object after its destructor has been run, as that's undefined behavior, and therefore the implementation can do anything it likes. Typically, compiler designers don't do anything special for undefined behavior, and so what happens is an artifact of what other design decisions were made. (This can cause really weird results sometimes.)
Therefore, once you've run the destructor, the compiler has no further obligation regarding that object. If you don't refer to it again, it doesn't matter. If you do refer to it, that's undefined behavior, and from the Standard's point of view the behavior doesn't matter, and since the Standard says nothing most compiler designers will not worry about what the program does.
In this case, the easiest thing to do is to leave the object untouched, since it isn't holding on to resources, and its storage was allocated as part of starting up the function and will not be reclaimed until the function exits. Therefore, the value of the data member will remain the same. The natural thing for the compiler to do when it reads ob2.day is to access the memory location.
Like any other example of undefined behavior, the results could change under any change in circumstances, but in this case they probably won't. It would be nice if compilers would catch more cases of undefined behavior and issue diagnostics, but it isn't possible for compilers to detect all undefined behavior (some occurs at runtime) and often they don't check for behavior they don't think likely.

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.

On calling destructor for an object, it is called two times? [duplicate]

This question already has answers here:
Destructor being called twice when being explicitly invoked
(10 answers)
Closed 8 years ago.
On calling desctructor explicitly, it is executed two times. What's the reason for that?
#include <iostream>
using namespace std;
class A
{
public:
int x;
A() { cout << "A's constructor called " << endl; }
~A(){
cout<<"A's desctructor called "<<endl;
}
};
int main()
{
A a;
A b;
a.~A();
}
Output:
A's constructor called
A's desctructor called
A's desctructor called
Well, you called it for 'a', and then 'the language' called it again for 'a' when the object went out of scope. And then, of course, 'the language' called it for b. By 'the language', I mean, of course, the very basic rule that automatic-scope objects are constructed as their scope initialize, and destructed when their scope ends.
Using explicit calls to destructors is rarely a good idea.
You shouldn't call the destructor by hand, it will get called automatically when the object goes out of scope.
The only place to manually call destructors is when you're writing your own allocator, but that is quite an advanced topic, so the rule of thumb would be to never call the destructor by hand.
[basic.life]/8:
If a program ends the lifetime of an object of type T with […]
automatic (3.7.3) storage duration and if T has a non-trivial
destructor, the program must ensure that an object of the original
type occupies that same storage location when the implicit destructor
call takes place; otherwise the behavior of the program is undefined.
Hence we cannot explain the behavior of your program in general, but we could say "For your implementation a particular execution behaved as if the destructor was called two times."
When a variable goes out of scope, its destructor is implicitly called.
If the there is no object of the appropriate type there, the behavior is undefined. Typically the compiler generates code that would call the destructor and does so blindly, as that makes the 'defined behavior' path efficient and simple, and the 'undefined behavior' path is considered your fault.
So what you are seeing is a symptom of undefined behavior. Your call of the destructor does not mean the compiler will not try to destroy the object.
In fact, if your object was slightly more complex, it could easily lead to a crash.
Don't call the destructor of an object directly unless you used placement new (a variant of new that constructs an object and does not allocate any memory) or the equivalent on it, and don't use placement new unless you really know what you are doing.
There is another valid use, where you destruct and reconstruct in the same place, but that is dangerous, usually a bad idea, and hard to get right.

How does the C++ runtime system know when objects go out of scope

I was wondering how the C++ runtime system detects when an object goes out of scope so that
it calls the destructor accordingly to free up the occupied memory.
Thanks.
The runtime doesn't - the compiler keeps tabs on scope and generates the code to call the destructor. If you make a simple test application and look at the generated disassembly you'll see explicit destructor calls.
Disassembly snippet from MSVC:
int main() {
std::string s1;
...
00971416 call dword ptr [__imp_std::basic_string<char,std::char_traits<char>,std::allocator<char> >::basic_string<char,std::char_traits<char>,std::allocator<char> > (979290h)]
...
{
std::string s2;
00971440 call dword ptr [__imp_std::basic_string<char,std::char_traits<char>,std::allocator<char> >::basic_string<char,std::char_traits<char>,std::allocator<char> > (979290h)]
...
}
00971452 call dword ptr [__imp_std::basic_string<char,std::char_traits<char>,std::allocator<char> >::~basic_string<char,std::char_traits<char>,std::allocator<char> > (979294h)]
...
}
0097146B call dword ptr [__imp_std::basic_string<char,std::char_traits<char>,std::allocator<char> >::~basic_string<char,std::char_traits<char>,std::allocator<char> > (979294h)]
This is known statically at compile time
{
string s; /* ctor called here */
} /* dtor called here */
Sometimes, it's more difficult
{
again:
{
string s; /* ctor called here */
goto again; /* now dtor of s is called here */
string q; /* ctor not called. not reached. */
} /* dtor of s and q would be called here. but not reached */
}
It has nothing to do with runtime. The compiler keeps track of scope of every lexical variable, and adds destructor calls.
"calling the destructor" and "freeing the memory associated with the variable" are two different things entirely.
A destructor is simply a function that C++ is nice enough to call for you when your object is going out of scope or is being explicitely deleted. The compiler generates this for you as others have said. Its a convenient way for you to clean up anything in your class that you need to clean up.
Freeing up the memory associated with something on the stack involves learning about how the stack operates. When a function is called, memory is allocated for everything on the stack by simply pushing onto the stack the amount of data needed for those variables. Though not explicitly stated in the C++ spec, the "push" really just involves letting the pointer to the top of the stack point higher (or lower) to make room for the extra variables. This is simple pointer addition. When the function returns, pointer subtraction occurs.
void foo()
{
HerClass y;
YourClass x; // stack incremented sizeof(YourClass) + sizeof(HerClass)
return; // destructor called,
// then stack decremented sizeof(YourClass) + sizeof(HerClass)
}
Everything is popped off the stack. You can learn more about this by reading about calling conventions.
Heap memory is explicitly manually controlled by the program. Unless code is doing the explicit heap management for you, you'll need to make sure you delete everything you new.
The scope ends with the scope. It doesn't "detect" it, the compiler writes the code in a way the destructor will be called in time.
E.g. the following code
if(something)
{
MyClass test;
test.doSomething();
}
Would result in machine code that does something like this:
evaluate the jump
jump down if required
allocate memory for test
call the constructor of MyClass on test
call doSomething on test
call the destructor of MyClass on test
deallocate memory
When the application enters a scoped environment (block, function call, etc.), the runtime loads the context (including local variables) for that block onto the stack. This is an actual stack data structure. As execution goes deeper and deeper into nested contexts, the stack gets higher and higher. If main() calls foo() which calls bar(), the stack will have main()s context on the bottom of the stack, then foo's context, then bar's. This is why infinite recursion results in "stack overflow" and throwing exceptions triggers "stack unwinding."
When execution exits that scope, that context is popped off the stack. In C++, popping objects of the stack includes invoking the destructor for those objects. So when bar() returns, its local variables will be popped off the stack, and the destructors for those variables will be invoked.
You're probably misunderstanding the characteristics of a few programming languages. C++ does not have a garbage collector, so it does not decide when an object has gone out of scope: the user does.
int main()
{
Obj * obj = new Obj;
Obj obj2;
delete obj;
}
In the function above, you create an object obj in the heap, and release it when you're no longer going to use it. The object obj2, on the other hand, just terminates its life at the end of main(), as any other variable. When an object terminates its life, the destructor of the object is called automatically; the compiler inserts the calls to these destructors automatically: at the end of the function, or when operator delete is invoked.

How do I call the class's destructor?

I have a simple C++ code, but I don't know how to use the destructor:
class date {
public:
int day;
date(int m)
{
day =m;
}
~date(){
cout << "I wish you have entered the year \n" << day;
}
};
int main()
{
date ob2(12);
ob2.~date();
cout << ob2.day;
return 0;
}
The question that I have is, what should I write in my destructor code, that after calling the destructor, it will delete the day variable?
Rarely do you ever need to call the destructor explicitly. Instead, the destructor is called when an object is destroyed.
For an object like ob2 that is a local variable, it is destroyed when it goes out of scope:
int main()
{
date ob2(12);
} // ob2.~date() is called here, automatically!
If you dynamically allocate an object using new, its destructor is called when the object is destroyed using delete. If you have a static object, its destructor is called when the program terminates (if the program terminates normally).
Unless you create something dynamically using new, you don't need to do anything explicit to clean it up (so, for example, when ob2 is destroyed, all of its member variables, including day, are destroyed). If you create something dynamically, you need to ensure it gets destroyed when you are done with it; the best practice is to use what is called a "smart pointer" to ensure this cleanup is handled automatically.
You do not need to call the destructor explicitly. This is done automatically at the end of the scope of the object ob2, i.e. at the end of the main function.
Furthermore, since the object has automatic storage, its storage doesn’t have to be deleted. This, too, is done automatically at the end of the function.
Calling destructors manually is almost never needed (only in low-level library code) and deleting memory manually is only needed (and only a valid operation) when the memory was previously acquired using new (when you’re working with pointers).
Since manual memory management is prone to leaks, modern C++ code tries not to use new and delete explicitly at all. When it’s really necessary to use new, then a so-called “smart pointer” is used instead of a regular pointer.
You should not call your destructor explicitly.
When you create your object on the stack (like you did) all you need is:
int main()
{
date ob2(12);
// ob2.day holds 12
return 0; // ob2's destructor will get called here, after which it's memory is freed
}
When you create your object on the heap, you kinda need to delete your class before its destructor is called and memory is freed:
int main()
{
date* ob2 = new date(12);
// ob2->day holds 12
delete ob2; // ob2's destructor will get called here, after which it's memory is freed
return 0; // ob2 is invalid at this point.
}
(Failing to call delete on this last example will result in memory loss.)
Both ways have their advantages and disadvantages. The stack way is VERY fast with allocating the memory the object will occupy and you do not need to explicitly delete it, but the stack has limited space and you cannot move those objects around easily, fast and cleanly.
The heap is the preferred way of doing it, but when it comes to performance it is slow to allocate and you have to deal with pointers. But you have much more flexibility with what you do with your object, it's way faster to work with pointers further and you have more control over the object's lifetime.
Only in very specific circumstances you need to call the destructor directly. By default the destructor will be called by the system when you create a variable of automatic storage and it falls out of scope or when a an object dynamically allocated with new is destroyed with delete.
struct test {
test( int value ) : value( value ) {}
~test() { std::cout << "~test: " << value << std::endl; }
int value;
};
int main()
{
test t(1);
test *d = new t(2);
delete d; // prints: ~test: 2
} // prints: ~test: 1 (t falls out of scope)
For completeness, (this should not be used in general) the syntax to call the destructor is similar to a method. After the destructor is run, the memory is no longer an object of that type (should be handled as raw memory):
int main()
{
test t( 1 );
t.~test(); // prints: ~test: 1
// after this instruction 't' is no longer a 'test' object
new (&t) test(2); // recreate a new test object in place
} // test falls out of scope, prints: ~test: 2
Note: after calling the destructor on t, that memory location is no longer a test, that is the reason for recreation of the object by means of the placement new.
In this case your destructor does not need to delete the day variable.
You only need to call delete on memory that you have allocated with new.
Here's how your code would look if you were using new and delete to trigger invoking the destructor
class date {
public: int* day;
date(int m) {
day = new int;
*day = m;
}
~date(){
delete day;
cout << "now the destructor get's called explicitly";
}
};
int main() {
date *ob2 = new date(12);
delete ob2;
return 0;
}
Even though the destructor seems like something you need to call to get rid of or "destroy" your object when you are done using it, you aren't supposed to use it that way.
The destructor is something that is automatically called when your object goes out of scope, that is, when the computer leaves the "curly braces" that you instantiated your object in. In this case, when you leave main(). You don't want to call it yourself.
You may be confused by undefined behavior here. The C++ standard has no rules as to what happens if you use an object after its destructor has been run, as that's undefined behavior, and therefore the implementation can do anything it likes. Typically, compiler designers don't do anything special for undefined behavior, and so what happens is an artifact of what other design decisions were made. (This can cause really weird results sometimes.)
Therefore, once you've run the destructor, the compiler has no further obligation regarding that object. If you don't refer to it again, it doesn't matter. If you do refer to it, that's undefined behavior, and from the Standard's point of view the behavior doesn't matter, and since the Standard says nothing most compiler designers will not worry about what the program does.
In this case, the easiest thing to do is to leave the object untouched, since it isn't holding on to resources, and its storage was allocated as part of starting up the function and will not be reclaimed until the function exits. Therefore, the value of the data member will remain the same. The natural thing for the compiler to do when it reads ob2.day is to access the memory location.
Like any other example of undefined behavior, the results could change under any change in circumstances, but in this case they probably won't. It would be nice if compilers would catch more cases of undefined behavior and issue diagnostics, but it isn't possible for compilers to detect all undefined behavior (some occurs at runtime) and often they don't check for behavior they don't think likely.