I’m just curious to know if there is any significant/serious difference in these three approaches of invoking destructor. Consider the following code. Please also consider the two cases mentioned in main().
class Sample
{
public:
~Sample()
{
cout << "destructor called" << endl;
}
void destroyApproach1() { this->~Sample(); }
void destroyApproach2() { delete this; }
};
void destroyApproach3(Sample *_this)
{
delete _this;
}
void TestUsingNew()
{
Sample *pSample[] = { new Sample(), new Sample(),new Sample()};
pSample[0]->destroyApproach1();
pSample[1]->destroyApproach2();
destroyApproach3(pSample[2]);
}
void TestUsingPlacementNew()
{
void *buf1 = std::malloc(sizeof(Sample));
void *buf2 = std::malloc(sizeof(Sample));
void *buf3 = std::malloc(sizeof(Sample));
Sample *pSample[3] = { new (buf1) Sample(), new (buf2) Sample(), new (buf3) Sample()};
pSample[0]->destroyApproach1();
pSample[1]->destroyApproach2();
destroyApproach3(pSample[2]);
}
int main()
{
//Case 1 : when using new
TestUsingNew();
//Case 2 : when using placement new
TestUsingPlacementNew();
return 0;
}
Please be specific when replying as to which case you’re answering to : case 1 or case 2, or both!
Also, I was trying to write TestUsingPlacementNew() in this way, but it’s throwing runtime exception (MSVC++2008). I don’t understand why:
void TestUsingPlacementNew()
{
const int size = sizeof(Sample);
char *buffer = (char*)std::malloc( size * 3);
Sample *pSample[] = { new (buffer) Sample(), new (&buffer[size]) Sample(),new (&buffer[2*size]) Sample()};
pSample[0]->destroyApproach1();
pSample[1]->destroyApproach2();
destroyApproach3(pSample[2]);
}
Maybe, memory padding and/or alignment could be the reason?
Related topic : Destructor not called after destroying object placement-new'ed
Yes, there is a huge difference between these approaches:
In
destroyApproach1, you only call the destructor of the object; you don’t actually free the memory that it occupied.In
destroyApproach2anddestroyApproach3you call the destructor of the object and you free the memory that the object occupied (by using thedeleteexpression). In the firstTestUsingPlacementNewtest, both of these are also wrong since the memory occupied by the object was initially allocated by a call tomalloc, not bynew.The runtime error in your last test occurs because you attempt to
deletethe object at index1in the array; the pointer to that element was not initially obtained from a call tonew. In the first example, it only “works” (where “works” really means “the behavior is undefined but it still appears to function correctly) because all three pointers are to independent heap allocations.