Reputation: 5450
I am trying to understand operator new and placement new. This is my code:
#include<iostream>
using namespace std;
class simpleClass
{
int objID;
public:
simpleClass(int ID) // constructor
{
objID = ID;
cout << "Constructing object with ID: " << objID << endl;
}
void printID()
{
cout << "Object ID: " << objID << endl;
}
~simpleClass()
{
cout << "Destructing object with ID: " << objID << endl;
}
};
int main(int argc, char** argv)
{
void *ptrToMem = operator new(sizeof(simpleClass)*3);
simpleClass *simpleClassPtr_1 = new (ptrToMem)simpleClass(1);
simpleClass *simpleClassPtr_2 = new ((simpleClass*)ptrToMem + sizeof(simpleClass))simpleClass(2);
simpleClass *simpleClassPtr_3 = new ((simpleClass*)ptrToMem + sizeof(simpleClass)*2)simpleClass(3);
simpleClassPtr_1->printID();
simpleClassPtr_2->printID();
simpleClassPtr_3->printID();
simpleClassPtr_1->~simpleClass();
simpleClassPtr_2->~simpleClass();
simpleClassPtr_3->~simpleClass();
operator delete(ptrToMem);
return 0;
}
I am simply trying to allocate memory for 3 objects and then call placement new on them. Everything seems to work fine until the operator delete where it gives me an exception (in VS2013).
What am I doing wrong? Is it not allowed to call operator delete when using placement new?
Upvotes: 2
Views: 115
Reputation: 37697
Problem here is use of the pointers.
This two lines are wrong:
simpleClass *simpleClassPtr_2 = new ((simpleClass*)ptrToMem + sizeof(simpleClass))simpleClass(2);
simpleClass *simpleClassPtr_3 = new ((simpleClass*)ptrToMem + sizeof(simpleClass)*2)simpleClass(3);
It should be like this:
simpleClass *simpleClassPtr_2 = new ((simpleClass*)ptrToMem + 1)simpleClass(2);
simpleClass *simpleClassPtr_3 = new ((simpleClass*)ptrToMem + 2)simpleClass(3);
Since pointer increase by one increases address by size of the pointed object so extra sizeof
is not needed.
You were exceeding range of allocated memory size, so it ended with a crash.
Upvotes: 3
Reputation: 8475
You messed up your pointer arithmetic:
simpleClass *simpleClassPtr_2 = new ((simpleClass*)ptrToMem + sizeof(simpleClass))simpleClass(2);
simpleClass *simpleClassPtr_3 = new ((simpleClass*)ptrToMem + sizeof(simpleClass)*2)simpleClass(3);
You are running placement new on the wrong element. Instead of initializing the adjacent simpleClass
, you are constructing a simpleClass number sizeof(simpleClass)
. The simplest thing is to replace the casting with char* casting:
simpleClass *simpleClassPtr_2 = new ((char*)ptrToMem + sizeof(simpleClass))simpleClass(2);
simpleClass *simpleClassPtr_3 = new ((char*)ptrToMem + sizeof(simpleClass)*2)simpleClass(3);
This works both with GCC and Clang.
Upvotes: 1
Reputation: 17415
You are accessing the allocated storage out-of-bounds:
(simpleClass*)ptrToMem + sizeof(simpleClass)
This should just be + 1
. Remember, pointer arithmetic works in steps of the pointee size anyway.
Upvotes: 2