I'm seeing a strange behavior in one of my projects. The circumstances are as follows:
- I have an object. Let's call
Victim
, which contains a pointer variable, a constructor and destructor. - I have another object, let's call
Perpetrator
, whose constructor accepts aVictim
object, and copies the pointer variable to a concrete variable inside. - I create a
Victim*
, and create the object withnew
, then supply this toPerpetrator
viaPerpetrator(*victim)
. - When the
Perpetrator
's constructor finishes,Victim
's destructor is called and object is deleted.
The problem is the only copy of the Victim
, which is poor
is completely destroyed during the construction process. Tidying up the program at the end via delete poor
will cause a double-free error.
The behavior is consistent in C++98/11, GCC 4.8.5, 7.x, and LLVM CLANG, hence it must be well defined. What is this behavior is called, and what are the semantics of it?
My theory is, since the constructor
accepts a concrete object, it's considered copied, so it's destructed when the constructor
/ function
is done.
Since I praise PoC||GTFO
, here's the code:
Clarification: The example is written intentionally, since it's a simplified model of a much more complex, but non-leaky and well-managed data structure complex. Removing all necessary bits made it look like an horribly broken code. In the real code Victim
is a long living data store and Perpetrator
is an interim storage variable used for processing said data.
#include <iostream>
using namespace std;
struct Victim
{
double* pointer;
Victim ()
{
this->pointer = new double(42.2);
}
~Victim ()
{
cout << "Destructor of the Victim is called." << endl;
delete this->pointer;
}
};
struct Perpetrator
{
double concrete;
Perpetrator (Victim victim)
{
concrete = *(victim.pointer);
}
};
int main ()
{
Victim* poor = new Victim();
Perpetrator cruel(*poor);
cout << cruel.concrete << endl;
}
Sample output:
./destructor_test
Destructor of the Victim is called.
42.2