Custom allocator with preallocated memory for STL containers

  allocator, c++, c++17, containers, stl

I’d like to use a std::vector which allocates the memory for its element from a preallocated buffer. So, I would like to provide a buffer pointer T* buffer of size n to std::vector.

I thought I could simply write a std::span-like class which also provides a push_back method; that would be exactly what I need. However, I’ve stumbled across the code from this post (see below) which seems to solve this problem with a custom allocator.

Nobody commented on that, but doesn’t the example with std::vector<int, PreAllocator<int>> my_vec(PreAllocator<int>(&my_arr[0], 100)); provided in the post end in undefined behavior? I’ve run the code with the Visual Studio 2019 implementation and at least this implementation is rebinding the provided allocator to allocate an element of type struct std::_Container_proxy. Now this should be a huge problem, since you’ve only provided memory to store your 100 int‘s. Am I missing something?


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

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

    PreAllocator(T* memory_ptr, std::size_t memory_size) : memory_ptr(memory_ptr), memory_size(memory_size) {}

    PreAllocator(const PreAllocator& other) throw() : memory_ptr(other.memory_ptr), memory_size(other.memory_size) {};

    template<typename U>
    PreAllocator(const PreAllocator<U>& other) throw() : memory_ptr(other.memory_ptr), memory_size(other.memory_size) {};

    template<typename U>
    PreAllocator& operator = (const PreAllocator<U>& other) { return *this; }
    PreAllocator<T>& operator = (const PreAllocator& other) { return *this; }
    ~PreAllocator() {}

    pointer allocate(size_type n, const void* hint = 0) { return memory_ptr; }
    void deallocate(T* ptr, size_type n) {}

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

int main()
{
    int my_arr[100] = { 0 };
    std::vector<int, PreAllocator<int>> my_vec(0, PreAllocator<int>(&my_arr[0], 100));
}

Source: Windows Questions C++

LEAVE A COMMENT