Placement new is usefull when you want to allocate an array of some type but you don't want to necessarily initialize every element with the default constructor. You allocate a space of unitialized memory (using malloc) and then use placement new to 'place' the object you want on an already allocated buffer.
It also lets you create arrays of objects that do not have a default constructor.
This comes with an added complexity that in order to free the memory used for this kind of allocation properly, that you have to first manually call the destructor of each object in the array. Then you must free the buffer.
#include <cstdlib>
struct Foo
{
Foo(int _x, double _y, float _z) : x(_x), y(_y), z(_z){}
private:
int x;
double y;
float z;
};
int main()
{
//allocate an empty buffer for 100 Foo objects using malloc
//memory allocated with malloc is uninitialized
Foo* buffer = (Foo*)(malloc(sizeof(Foo) * 100));
//place the Foo objects you want on the buffer
for(int i = 0; i < 100; ++i)
{
new (buffer + i) Foo(1, 2.0, 3.0);
}
//in order to properly free the memory you need to do this:
for(int i = 0; i < 100; ++i)
{
//explicitly call the destructor
buffer[i].~Foo();
}
//free the buffer
free(buffer);
return 0;
}
//this is much faster than simply allocating using new Foo[100] then
//running through the array again and assigning the Foos to want you want
//them to be.
//For 2 Reasons :
// 1. The buffer is already allocated, so one doesn't need to be retrieved from
// the heap storage.
// 2. The allocated buffer is unitialized so there was no wasted time going through
// the array creating every object using the default constructor with new[]
// 3. Sometimes you may need to use placement new to create arrays of objects
// which do not have default constructors because that is the only constructor
// that new[] will call automatically for you.
Hi R0Mai and darkestfright:
Thank you for your explaining. But I don't think it's "placement new", because the code use 'int' to place 'void *'.
this a part of my code(sorry I can't post it all):
and I'm sure that the memNeeded is a int, it isn't converted from a pointer.
And the class TpCallRecordBlob is a class only includes some functions, some functions like this:
1 2 3 4 5
void TpCallRecordBlob::functionA(void *inputBuff, int inputBuffLen)
{
int offset = GetOffset();
memcpy(this + offset, inputBuff, inputBuffLen);
}
It confuse me~
BTW, darkestfright, in your code line 22, it should be like this?
1 2 3 4 5
for(int i = 0; i < 100; ++i)
{
new (buffer + i) Foo(1, 2, 3);
}
In placement new syntax, you pass a pointer, not a number there. Although I can imagine that you can overload operatornew() in a way, so that it is valid to write something like this. I'm no expert in this though. Check the implementation of TpCallRecordBlob, there might be some overloading of operator new.