operator delete使用placement new抛出异常

问题描述 投票:2回答:3

我想了解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?

c++ heap-memory
3个回答
3
投票

这里的问题是使用指针。

这两行是错误的:

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。您超出了分配的内存大小范围,因此以崩溃结束。


2
投票

您正在访问分配的存储超出范围:

(simpleClass*)ptrToMem + sizeof(simpleClass)

这应该只是+ 1。请记住,无论如何,指针算法都以指针大小的步长工作。


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。

© www.soinside.com 2019 - 2024. All rights reserved.