Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In C++11, how can I call new and reserve enough memory for the object?

I have a class that is described that way :

class Foo {
    int size;
    int data[0];

public:
    Foo(int _size, int* _data) : size(_size) {
        for (int i = 0 ; i < size ; i++) {
            data[i] = adapt(_data[i]);
        }
    }

    // Other, uninteresting methods
}

I cannot change the design of that class.

How can I create an instance of that class ? Before calling the constructor, I have to make it reserve enough memory to store its data, so it has to be on the heap, not on the stack. I guess I want something like

Foo* place = static_cast<Foo*>(malloc(sizeof(int) + sizeof(int) * size));
*place = new Foo(size, data);  // I mean : "use the memory allocated in place to do your stuff !"

But I can't find a way to make it work.

EDIT : as commentators have noticed, this is not a very good overall design (with non-standards tricks such as data[0]), alas this is a library I am forced to use...

like image 918
Fabien Avatar asked May 30 '13 14:05

Fabien


1 Answers

You could malloc the memory for the object and then use a placement new to create the object in the previously allocated memory :

void* memory = malloc(sizeof(Foo) + sizeof(int) * size);
Foo* foo = new (memory) Foo(size, data);

Note that in order to destroy this object, you can't use delete. You would have to manually call the destructor and then use free on the memory allocated with malloc :

foo->~Foo();
free(memory); //or free(foo);

Also note that, as @Nikos C. and @GManNickG suggested, you can do the same in a more C++ way using ::operator new :

void* memory = ::operator new(sizeof(Foo) + sizeof(int) * size);
Foo* foo = new (memory) Foo(size, data);
...
foo->~Foo();
::operator delete(memory); //or ::operator delete(foo);
like image 166
zakinster Avatar answered Oct 31 '22 22:10

zakinster