Reputation: 3164
I am new to placement new
so I wanted to separate allocation from initialization using it along operator new
to allocate and construct an array of my user-defined type class Foo
.
here is what I've tried:
struct Foo{
Foo(int x) : x_(x){
std::cout << "Foo(int)\n";
}
~Foo(){
std::cout << "~Foo()\n";
}
int x_ = 0;
};
int main(){
Foo* pf = static_cast<Foo*>(operator new[](10 * sizeof(Foo) ) );
for(int i = 0; i != 10; ++i)
new(pf + i)Foo(i * 7);
for(int i = 0; i != 10; ++i)
std::cout << pf[i].x_ << ", ";
std::cout << '\n';
for(int i = 0; i != 10; ++i)
pf[i].~Foo();
operator delete[](pf);
}
class allocator
works? (separate allocation from initialization).Upvotes: 3
Views: 175
Reputation: 238311
please guide me if I've missed something.
Seems fine for Foo
. But more generally, the approach isn't exception safe. If one of the class constructors throw, then your allocation leaks and the previously constructed objects won't be destroyed.
And is this similar to how class allocator works?
Quite similar. A few differences:
std::allocator<T>::allocate
uses ::operator new(std::size_t, std::align_val_t)
and std::allocator<T>::deallocate
calls ::operator delete(void*, std::align_val_t)
since C+++17. This is needed to support over-aligned types.std::allocator<T>::allocate
actually does start the lifetime of an array of T
(without starting the lifetime of the objects). There's technically no way to implement that in standard C++ for non-trivial types.Upvotes: 3