Custom allocator for nested containers

  allocator, c++, memory-management

I am working on custom allocators. So far, I have tried to work on simple containers: std::list, std::vector, std::basic_string, etc…

My custom allocator is a static buffer allocator, its implementation is straightforward:

#include <memory>

template <typename T>
class StaticBufferAlloc : std::allocator<T>
{
private:
    T *memory_ptr;
    std::size_t memory_size;

public:
    typedef std::size_t size_type;
    typedef T *pointer;
    typedef T value_type;

    StaticBufferAlloc(T *memory_ptr, size_type memory_size) : memory_ptr(memory_ptr), memory_size(memory_size) {}
    StaticBufferAlloc(const StaticBufferAlloc &other) throw() : memory_ptr(other.memory_ptr), memory_size(other.memory_size){};
    pointer allocate(size_type n, const void *hint = 0) { return memory_ptr; } // when allocate return the buffer
    void deallocate(T *ptr, size_type n) {}                                    // empty cause the deallocation is buffer creator's responsability

    size_type max_size() const { return memory_size; }
};

I am using it in this fashion:

  using inner = std::vector<int, StaticBufferAlloc<int>>;
  int buffer[201];
  auto alloc1 = StaticBufferAlloc<int>(&buffer[100], 50);
  inner v1(0, alloc1);
  assert(v1.size() == 0);
  const int N = 10; 
  // insert 10 integers
  for (size_t i = 0; i < N; i++)  {
    v1.push_back(i);
  }
  assert(v1.size() == N);

All good so far, when I grow N past the max buffer size it throws and that’s expected.


Now, I am trying to work with nested containers. In short, am trying to have a vector of the vector (matrix), where the parent vector and all its underlying elements (that are vectors i.e. containers) share the same static buffer for allocation. It looks like scoped_allocator can be a solution for my problem.

  using inner = std::vector<int, StaticBufferAlloc<int>>;
  using outer = std::vector<inner, std::scoped_allocator_adaptor<StaticBufferAlloc<inner>>>;

  int buffer[201];
  auto alloc1 = StaticBufferAlloc<int>(&buffer[100], 50);
  auto alloc2 = StaticBufferAlloc<int>(&buffer[150], 50);
  inner v1(0, alloc1);
  inner v2(0, alloc2);
  assert(v1.size() == 0);
  assert(v2.size() == 0);

  const int N = 10; 
  // insert 10 integers
  for (size_t i = 0; i < N; i++)
  {
    v1.push_back(i);
    v2.push_back(i);
  }
  assert(v1.size() == N);
  assert(v2.size() == N);

  outer v // <- how to construct this vector with the outer buffer? 
  v.push_back(v1);
  v.push_back(v2); 
  ...

My question is how to initialize the outer vector on its constructor call with its static buffer?

Source: Windows Questions C++

LEAVE A COMMENT