运算符delete抛出异常,位置为new

时间:2018-09-03 07:56:04

标签: c++ heap-memory

我试图了解新的操作员和新的位置。 这是我的代码:

#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个对象分配内存,然后在它们上调用new。 在操作员删除给我一个异常的地方之前,一切似乎都工作正常(在VS2013中)。

我在做什么错? 使用新的展示位置时,不允许呼叫操作员删除吗?

3 个答案:

答案 0 :(得分: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。 您超出了已分配的内存大小范围,因此以崩溃告终。

答案 1 :(得分:2)

您正在访问分配的存储空间:

(simpleClass*)ptrToMem + sizeof(simpleClass)

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

答案 2 :(得分:1)

您弄乱了指针算法:

simpleClass *simpleClassPtr_2 = new ((simpleClass*)ptrToMem + sizeof(simpleClass))simpleClass(2);
simpleClass *simpleClassPtr_3 = new ((simpleClass*)ptrToMem + sizeof(simpleClass)*2)simpleClass(3);

您在错误的元素上运行了新的展示位置。您无需构造相邻的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。