简体   繁体   中英

operator delete throwing an exception with placement new

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?

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.

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.

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM