I just came across some container implementation in C++. That class uses an internal buffer to manage its objects. This is a simplified version without safety checks:
template <typename E> class Container
{
public:
Container() : buffer(new E[100]), size(0) {}
~Container() { delete [] buffer; }
void Add() { buffer[size] = E(); size++; }
void Remove() { size--; buffer[size].~E(); }
private:
E* buffer;
int size;
};
AFAIK this will construct/destruct E objects redundantly in Container() and ~Container() if new/delete are not customized. This seems dangerous.
Is using placement new in Add() the best way to prevent dangerous redundant constructor / destructor calls (apart from binding the class to a fully featured pool)?
When using placement new, would new char[sizeof(E)*100] be the correct way for allocating the buffer?
It would appear so. The
newed array already applies the default constructor and thedelete[]would call destructor as well for all the elements. In effect, theAdd()andRemove()methods add little other than maintain thesizecounter.The best would be to opt for the
std::allocatorthat handles all of the memory issues for you already.Using a placement
newand managing the memory yourself requires you to be aware of a number of issues (including);None of these are impossible to surmount, it has just already been done in the standard library. If you are interested in pursuing a custom allocator, the global allocation functions (
void* operator new (std::size_t count);) would be the appropriate starting point for the memory allocations.Without further explanation on the original purpose of the code - a
std::vectoror astd::arraywould be far better options for managing the elements in the container.