c++memory-managementplacement-newobject-constructionobject-destruction

Using placement new in a container


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?


Solution

  • AFAIK this will construct/destruct E objects redundantly

    It would appear so. The newed array already applies the default constructor and the delete[] would call destructor as well for all the elements. In effect, the Add() and Remove() methods add little other than maintain the size counter.

    When using placement new, would new char[sizeof(E)*100] be the correct way for allocating the buffer?

    The best would be to opt for the std::allocator that handles all of the memory issues for you already.

    Using a placement new and 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::vector or a std::array would be far better options for managing the elements in the container.