Просто из любопытства, является ли законным?
X* p = static_cast<X*>(operator new[](3 * sizeof(X)));
new(p + 0) X();
new(p + 1) X();
new(p + 2) X();
delete[] p; // Am I allowed to use delete[] here? Or is it undefined behavior?
Аналогично:
X* q = new X[3]();
(q + 2)->~X();
(q + 1)->~X();
(q + 0)->~X();
operator delete[](q);