Search code examples
c++memoryatomicsmart-pointersallocation

Custom allocator with compile time array


I want to have a defined allocation limit (for my µC) to allocate "dynamic" memory.

My code:

template<class T, size_t COUNT>
class SimpleAllocator
{
public:
  using value_type = T;

  template<class U>
  struct rebind
  {
    using other = SimpleAllocator<U, COUNT>;
  };

  SimpleAllocator() noexcept
  {
  }

  template<class U, size_t COUNT_U>
  SimpleAllocator(SimpleAllocator<U, COUNT_U> const &other) noexcept
  {
  }

  value_type* allocate(std::size_t p_Count)
  {
    return nullptr;
  }

  void deallocate(value_type* p_Chunk, std::size_t) noexcept
  {
  }

  T m_Chunks[COUNT];
};

If I use this allocator with the smart pointer function: std::allocate_shared I get an compiler error:

error: constructor for 'SimpleAllocator<std::_Sp_counted_ptr_inplace<int, 
  SimpleAllocator<int, 10>, __gnu_cxx::_Lock_policy::_S_atomic>, 10>' must
  explicitly initialize the member 'm_Chunks' which does not have a default
  constructor

I understand this error but I cannot resolve it. How can I initialize a object like this one:

std::_Sp_counted_ptr_inplace<int, SimpleAllocator<int, 10>,
  __gnu_cxx::_Lock_policy::_S_atomic>

Live Example.


Solution

  • You don't want to initialize any objects in allocator, you just need to allocate memory. So you have to replace this

    T m_Chunks[COUNT];
    

    with for example

    alignas(T) char m_Chunks[COUNT * sizeof(T)];
    

    and update all the bookkeeping (which you haven't shown) accordingly.

    That said, having a buffer right inside an allocator itself isn't a good idea (unless you know exactly what you are doing). The allocator is supposed to be a lightweight object, because it's stored by value in containers and is copied during many operations.