As mentioned in this answer simply calling the destructor for the second time is already undefined behavior 12.4/14(3.8).
For example:
class Class {
public:
~Class() {}
};
// somewhere in code:
{
Class* object = new Class();
object->~Class();
delete object; // UB because at this point the destructor call is attempted again
}
In this example the class is designed in such a way that the destructor could be called multiple times - no things like double-deletion can happen. The memory is still allocated at the point where delete
is called - the first destructor call doesn't call the ::operator delete()
to release memory.
For example, in Visual C++ 9 the above code looks working. Even C++ definition of UB doesn't directly prohibit things qualified as UB from working. So for the code above to break some implementation and/or platform specifics are required.
Why exactly would the above code break and under what conditions?
The constructor code is the construction of t1. Then a copy constructor is used when it is pushed back on the vector. When the clear() is called, it calls the destructor for the object in the vector. Then t1's destructor is called when it goes out of scope.
Why is the destructor being called three times?
However, in your current implementation you're actually returning a shallow copy of NodeContainer. Once your copy goes out of scope its destructor is called, which deallocates its memory, which in this case is the original memory of your member, effectively making your member invalid.
A destructor is a member function that is invoked automatically when the object goes out of scope or is explicitly destroyed by a call to delete .
I think your question aims at the rationale behind the standard. Think about it the other way around:
So why again should this not cause undefined behavior?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With