(Note: this question was motivated by trying to come up with preprocessor hackery to generate a no-op allocation to answer this other question:
Macro that accept new
Peforming placement-new several times on the same block of memory is perfectly fine. Moreover, however strange it might sound, you are not even requred to destruct the object that already resides in that memory (if any). The standard explicitly allows that in 3.8/4
4 A program may end the lifetime of any object by reusing the storage which the object occupies or by explicitly calling the destructor for an object of a class type with a non-trivial destructor. For an object of a class type with a non-trivial destructor, the program is not required to call the destructor explicitly before the storage which the object occupies is reused or released;[...]
In other words, it is your responsibility to take into account the consequences of not calling the destructor for some object.
However, calling the destructor on the same object twice as you do in your code is not allowed. Once you created the second object in the same region of memory, you effectively ended the lifetime of the first object (even though you never called its destructor). Now you only need to destruct the second object.
foo* p1 = new (buffer) foo(1);
foo* p2 = new (buffer) foo(2);
p1->~foo();
p2->~foo();
You are destructing the same object twice, and that alone is undefined behavior. Your implementation may decide to order a pizza when you do that, and it would still be on the right side of the spec.
Then there is the fact that your buffer may not be properly aligned to emplace an object of type foo, which is again non standard C++ (according to C++03, I think C++11 relaxes this).
Update: Regarding the question specified in the title,
Is it well-defined/legal to placement-new multiple times at the same address?
Yes, is it well-defined to placement-new multiple times at the same address, provided that it points to raw memory.
No - this doesn't look right.
When you use placement new
, the object will be constructed at the address you pass. In this example you're passing the same address (i.e. &buffer[0]) twice, so the second object is just obliterating the first object that's already been constructed at this location.
EDIT: I don't think I understand what you're trying to do.
If you have a general object type (that may have non-trivial ctor/dtor's that might allocate/deallocate resources) and you obliterate the first object by placement new
'ing over the top of it without first explicitly calling it's destructor, this will at least be a memory leak.