Good Ol' new
Before discussing array allocations, let's remind ourselves the basics i.e., how to use placement
new. The scalar (i.e. non-array) version placement
new takes a user-supplied address on which it constructs an object. Unlike the ordinary
new operator, placement
new doesn't allocate storage for the object; it merely constructs it on the memory address given. Here's an example:
#include <new> //required for using placement new
class Widget {..};
char* buff=new char [sizeof (Widget)];//preallocate storage
Widget* pw= new(buff) Widget; //construct Widget on buff
pw->Draw(); //use Widget
The destruction of such an object consists of two steps. First, invoke its destructor explicitly:
pw->~Widget(); //explicit destructor invocation
Then, reclaim the raw memory:
delete[] buff;
Array Allocation
Array allocation requires the same steps, albeit with some subtle differences. First, allocate a buffer large enough to hold an array of the desired type:
const int ARRSIZE=5;
char * buff=new [sizeof(Widget)*ARRSIZE];
Next, construct an array of
ARRSIZE objects on the buffer using placement
new []:
Widget* pw=new(buff) Widget[ARRSIZE];//construct an array
You can now use this array as usual:
for (int i=0; i<ARRSIZE; i++)
{
pw[i].Draw();
}
Note: Remember that in order to create an array of
X, class
X must have an accessible default constructor.
Array Destruction
To destroy such an array, call each element's destructor explicitly:
int i=ARRSIZE;
while (i)
pw[--i].~Widget()
Notice that the
while-loop uses a descending order to preserve the
canonical destruction order of C++: the array element with the highest index is destroyed first, because it was constructed last.