While taking a test for a video games company based in California, I had to create elements in an already allocated buffer.
The tricky part of this was that the constructor of the object saved ‘this’ in a attribute field, and the test program always compared this value to the address of the object, failing if different.
As I was working with generic objects, I wasn’t supposed to know that, but still had to handle it. So I couldn’t update this address field inside the object after having copied it in my buffer to its new address.
One can think that we just have to call the object constructor again once it has been initialized:
unsigned size = 10; // This is already given, we have to cope with it... char *charBuffer = new char[sizeof(T)*size]; // We have a generic type T with a constructor T(args) T *buffer = reinterpret_cast<T*>(charBuffer); for (unsigned i=0; i < sizeof(T)*size; i++) { buffer[i].T(args); }
But this would mean that we have forgotten that constructors cannot be directly called:
error: invalid use of ‘T::T(args)’
The only way was to create the object directly inside the buffer, so that the constructor will be called with the correct address.
After having combed the web, I found this post, giving the solution:
unsigned size = 10; // This is already given, we have to cope with it... char *charBuffer = new char[sizeof(T)*size]; // We have a generic type T with a constructor T(args) T *buffer = reinterpret_cast<T*>(charBuffer); for (unsigned i=0; i < size; i++) { new (buffer+i)T(args); }
This way, each element of my buffer will be constructed with the address it will have for its whole life.