Is `new (this) MyClass();` undefined behaviour after directly calling the destructor? - c++

In this question of mine, #DeadMG says that reinitializing a class through the this pointer is undefined behaviour. Is there any mentioning thereof in the standard somewhere?
Example:
#include <iostream>
class X{
int _i;
public:
X() : _i(0) { std::cout << "X()\n"; }
X(int i) : _i(i) { std::cout << "X(int)\n"; }
~X(){ std::cout << "~X()\n"; }
void foo(){
this->~X();
new (this) X(5);
}
void print_i(){
std::cout << _i << "\n";
}
};
int main(){
X x;
x.foo();
// mock random stack noise
int noise[20];
x.print_i();
}
Example output at Ideone (I know that UB can also be "seemingly correct behaviour").
Note that I did not call the destructor outside of the class, as to not access an object whose lifetime has ended. Also note, that #DeadMG says that directly calling the destructor is okay as-long-as it's called once for every constructor.

That would be okay if it didn't conflict with stack unwinding.
You destroy the object, then reconstruct it via the pointer. That's what you would do if you needed to construct and destroy an array of objects that don't have a default constructor.
The problem is this is exception unsafe. What if calling the constructor throws an exception and stack is unwound and the destructor is called for the second time?
{
X x;
x.foo(); // here ~X succeeds, then construction fails
} //then the destructor is invoked for the second time.
That aspect specifically would be undefined behavior.

Apart from #sharptooth's answer. I am just wondering for 2 more cases. At least they are worth mentioning.
(1) If the foo() was invoked using a pointer on heap which was allocated using malloc(). The constructor is not called. Can it be safe ?
(2) What if the derived class is calling foo(). Will it be a good behavior ? e.g.
struct Y : X {}; // especially when there is virtual ~X()
int main ()
{
Y y;
y.foo();
}

Related

Double free() or corruption:C++

Why if I write a code like this (X is a generic class) calling constructor and destructor
int main()
{
X one ();
one.~X();
return 0;
}
give me this error?
Double free() or corruption:C++
You should almost never call destructors explicitly, they are called implicitly when an object falls out of scope (or deleted, if allocated on heap). First you manually deallocate background's array by calling background.~Y(), and next this same array tries to get deallocated once more at the next }.
Calling the destructor of an object is almost always wrong. Actually I never came across a situation where this was right. You need to read about RAII and maybe this example will help you to understand why you get the error:
#include <iostream>
struct Foo{
Foo() { std::cout << " constructor " << std::endl; }
~Foo() { std::cout << " destructor " << std::endl; }
};
int main(){
Foo foo;
// foo.~Foo(); // <- never ever do this !
} // <- object is destroyed here !
Run this and you will see, that the destructor is called already. Destroying an already destroyed object leads to the error you get.

Destructor direct call in C++

Hence the code below.
class A
{
int x;
public:
A() {x = 3;}
};
int main()
{
void* mem = operator new(sizeof(A));
A* obj = static_cast<A*>(new(mem)(A));
std::cout << obj->x << std::endl;
obj->A::~A();
std::cout << obj->x << std::endl;
}
My first question is: Why I can directly call the destructor of A;
My second question is: Why the output is:
3
3
The the object obj is not deleted after the destructor call? The second 3 bothers me.
Why can I call the destructor?
Because it is a public member function, and you can call public member functions.
Why is the object not deleted?
In your specific case, it still exists because A has a trivial destructor.
If it had a non-trivial one, it would be deleted in the sense that you are not allowed to use it anymore. If you do anyways, you have undefined behavior.
For a more detailed discussion on that read this.

Is the memory automatically reclaimed when a delegating constructor throws?

Following on from this: Is the destructor called when a delegating constructor throws?
class X
{
public:
X() {};
X(int) : X() { throw std::exception(); }
X(double) { throw std::exception(); }
~X();
};
What about dynamic memory? Normally an exception in the constructor means the object was not fully constructed and thus the memory is cleanedup and not lost.
But the argument in the previous question is that the object is fully constructed (or fully initialized) after the delegate completes. How does this affect reclaiming the memory? I would hope that memory is still cleanedup!
int main()
{
new X(5); // new called
// delete called because delegate completed.
// I assume:
// Memory re-claimed (because constructor did not complete)
// I assume the C++11 standard adjusted to compensate.
// As a constructor did complete.
}
Compared too:
int main()
{
new X(5.0); // new called
// Delete **NOT** called
// Memory re-claimed (because constructor did not complete)
}
If the memory is cleaned up, then the definition of when the memory is cleanup needs to be altered from C++03 spec. How is the behavior changed?
If the constructor called by new throws an exception then the memory allocated by new is automatically deallocated. Delegating constructors change nothing in this regard.
If any part of the object initialization described above76 terminates by throwing an exception and a suitable deallocation function can be found, the deallocation function is called to free the memory in which the object was being constructed
                                                                                                       — C++11 [expr.new] 5.3.4/18
The 'any part of the object initialization' described includes both the constructor calls and evaluation of the expressions passed to the constructor.
Also, this behavior is specified identically in the C++98 standard [C++98 5.4.3/17]. The only difference delegating constructors make is if your mental model was previously based on the object being completely constructed or not. Given delegating constructors that's no longer equivalent to the actual specification of when deallocation occurs.
In your first example:
new X(5);
The order of events is:
allocation function called
X(int) called
X() called (and exits successfully)
X(int) throws an exception
~X() called
X(int) exits via exception
deallocation function called because object initialization failed
exception continues to propagate normally
With the second example
new X(5.0);
allocation function called
X(double) called
X(double) fails with an exception
deallocation function called because object initialization failed
exception continues to propagate normally
You can observe this behavior by replacing the allocation and deallocation functions:
#include <iostream>
#include <cstdlib>
#include <stdexcept>
#include <new>
void *operator new(std::size_t s) {
if (void *ptr = std::malloc(s)) {
std::cout << "allocation\n";
return ptr;
}
throw std::bad_alloc{};
}
void operator delete(void *ptr) noexcept {
if (ptr) {
std::cout << "deallocation\n";
std::free(ptr);
}
}
struct S {
S() {};
S(int) : S{} { throw std::exception(); }
S(double) { throw std::exception(); }
~S() { std::cout << "destructor\n"; }
};
int main() {
std::cout << "test 1\n";
try {
new S(1);
} catch(...) {
std::cout << "exception caught\n";
}
std::cout << "test 2\n";
try {
new S(1.);
} catch(...) {
std::cout << "exception caught\n";
}
}
The correct output of this program is:
test 1
allocation
destructor
deallocation
exception caught
test 2
allocation
deallocation
exception caught

Order of the destructor calls at the end of block\program [duplicate]

This question already has answers here:
Order and point of calling destructor
(4 answers)
Closed 9 years ago.
So at the end of the block\program the compiler calls on it's own the destructors for the objects that were defined. Is there a particular order in which the destructors are called?
class Foo1{
public:
~Foo1 () {cout << "Foo1 DTOR" << endl;}
};
class Foo2{
public:
~Foo2 () {cout << "Foo2 DTOR" << endl;}
};
void main(){
Foo1 A;
Foo2 B;
}
running this program I had the output:
Foo2 DTOR
Foo1 DTOR
Is it how it always works starting from the last defined object and ending with the first one? Or this behavior ca not be predicted and my output is something particular to this situation?
Destructors are always run in the reverse order to constructors (except dynamic memory where programmer explicitly deletes objects in memory (with calling it's destructor)).
In you example A is places before B, so it's constructor called earlier. That's why it's destructor was called after B's destructor.
LIFO ordering for object lifetimes is the only thing that makes sense. Consider this moderately representative example:
struct ValueHolder
{
int value;
ValueHolder() : value(0) { }
~ValueHolder() { std::cout << "Value = " << value << "\n"; }
};
struct HolderGuard
{
ValueHolder & h;
HolderGuard(ValueHolder & vh) : vh(h) { }
~HolderGuard() { ++h.value; }
};
Usage:
int main()
{
ValueHolder h;
HolderGuard(h);
}
This will first increment the held value, and then print it. It would be impossible for later things to depend on earlier things if the later things weren't destroyed first.
(The beauty of the example construction is that it does the right thing even when later code throws an exception.)

Meaning of "~" (tilde) symbol in C++?

// AirlineTicket.h
class AirlineTicket
{
public:
AirlineTicket();
~AirlineTicket();
int getNumberOfMiles();
private:
int mNumberOfMiles;
};
I want now what is the meaning of ~AirlineTicket(); in this code?
I don't know the meaning of ~ (tilde).
It is the destructor.
It gets called when you destroy (reaching end of scope, or calling delete to a pointer to) the instance of the object.
In the context you're using it, it defines a destructor.
In other context such as the following one, it's also called bitwise negation (complement):
int a = ~100;
int b = ~a;
Output: (ideone)
-101
100
~ signs that it is a destructor and when ever the object goes out of scope, corresponding destructor is called.
When the destructor is called ?
Taking an example -
#include <iostream>
class foo
{
public:
void checkDestructorCall() ;
~foo();
};
void foo::checkDestructorCall()
{
foo objOne; // objOne goes out of scope because of being a locally created object upon return of checkDestructorCall
}
foo:: ~foo()
{
std::cout << "Destructor called \t" << this << "\n";
}
int main()
{
foo obj; // obj goes of scope upon return of main
obj.checkDestructorCall();
return 0;
}
Results on my system:
Destructor called 0xbfec7942
Destructor called 0xbfec7943
This example just serves to indicate when a destructor is called. But destructor is written only when the class manages resources.
When class manages resources?
#include <iostream>
class foo
{
int *ptr;
public:
foo() ; // Constructor
~foo() ;
};
foo:: foo()
{
ptr = new int ; // ptr is managing resources.
// This assignment can be modified to take place in initializer lists too.
}
foo:: ~foo()
{
std::cout << "Destructor called \t" << this << "\n";
delete ptr ; // Returning back the resources acquired from the free store.
// If this isn't done, program gives memory leaks.
}
int main()
{
foo *obj = new foo;
// obj is pointing to resources acquired from free store. Or the object it is pointing to lies on heap. So, we need to explicitly call delete on the pointer object.
delete obj ; // Calls the ~foo
return 0;
}
Results on my system:
Destructor called 0x9b68008
And in the program, you posted I don't see a need to write destructor. Hope it helps !
It's the class destructor. You might want to pick up an introductory text on C++ development, as destructors are a fundamental concept in OOP. There is a good reference site here, and the C++ FAQ is another good resource.
~AirlineTicket(); is the destructor for the class AirlineTicket
see this link for further reference
The destructor is called when you delete the object of that class, to free any memory allocated or resources being used by the object.
~ introduces a destructor. It's used because (a) it was available, ad (b) ~ is one (of several) mathematical notation for "not".
This indicates destructor of class.
http://publib.boulder.ibm.com/infocenter/comphelp/v8v101/index.jsp?topic=%2Fcom.ibm.xlcpp8a.doc%2Flanguage%2Fref%2Fcplr380.htm