madu
madu

Reputation: 5450

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?

Upvotes: 2

Views: 115

Answers (3)

Marek R
Marek R

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

Michael Veksler
Michael Veksler

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

Ulrich Eckhardt
Ulrich Eckhardt

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

Related Questions