我想了解operator new和placement new。这是我的代码:
#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;
}
我只是尝试为3个对象分配内存,然后在它们上调用placement new。一切似乎工作正常,直到操作员删除它给我一个例外的地方(在VS2013中)。
我究竟做错了什么?使用贴图新建时,是否不允许调用operator delete?
这里的问题是使用指针。
这两行是错误的:
simpleClass *simpleClassPtr_2 = new ((simpleClass*)ptrToMem + sizeof(simpleClass))simpleClass(2);
simpleClass *simpleClassPtr_3 = new ((simpleClass*)ptrToMem + sizeof(simpleClass)*2)simpleClass(3);
它应该是这样的:
simpleClass *simpleClassPtr_2 = new ((simpleClass*)ptrToMem + 1)simpleClass(2);
simpleClass *simpleClassPtr_3 = new ((simpleClass*)ptrToMem + 2)simpleClass(3);
由于指针增加1会增加地址与指向对象的大小,因此不需要额外的sizeof
。您超出了分配的内存大小范围,因此以崩溃结束。
您正在访问分配的存储超出范围:
(simpleClass*)ptrToMem + sizeof(simpleClass)
这应该只是+ 1
。请记住,无论如何,指针算法都以指针大小的步长工作。
你弄乱了你的指针算术:
simpleClass *simpleClassPtr_2 = new ((simpleClass*)ptrToMem + sizeof(simpleClass))simpleClass(2);
simpleClass *simpleClassPtr_3 = new ((simpleClass*)ptrToMem + sizeof(simpleClass)*2)simpleClass(3);
您正在错误的元素上运行placement new。您正在构建一个simpleClass数字simpleClass
,而不是初始化相邻的sizeof(simpleClass)
。最简单的方法是用char *铸件替换铸件:
simpleClass *simpleClassPtr_2 = new ((char*)ptrToMem + sizeof(simpleClass))simpleClass(2);
simpleClass *simpleClassPtr_3 = new ((char*)ptrToMem + sizeof(simpleClass)*2)simpleClass(3);
这适用于GCC和Clang。