3

I'm now beginning to learn how to write allocators and I want to write a simple allocator that uses a provided fixed-size pool of memory.

So far I have:

template<typename T>
class PtrAllocator : public BasicAllocator<T>
{
    private:
        T* ptr;

    public:
        typedef typename BasicAllocator<T>::pointer pointer;
        typedef typename BasicAllocator<T>::size_type size_type;
        typedef typename BasicAllocator<T>::value_type value_type;

        template<typename U>
        struct rebind {typedef PtrAllocator<U> other;};

        PtrAllocator(T* ptr) : ptr(ptr) {}

        pointer allocate(size_type n, const void* hint = 0) {return static_cast<pointer>(&ptr[0]);}
        void deallocate(void* ptr, size_type n) {}
        size_type max_size() const {return 5000;}
};


int main()
{
    int* ptr = new int[5000];
    std::vector<int, PtrAllocator<int>> v(PtrAllocator<int>(ptr));
    v.reserve(100);

    delete[] ptr;
}

The above gives me the following error:

request for member 'reserve' in 'v', which is of non-class type 'std::vector<int, PtrAllocator<int> >(PtrAllocator<int>)'

I want to be able to somehow pass my ptr to my allocator so that std::vector uses that.

Any ideas how I can do this?

EDIT: I solved it. I had to use the following for main:

int main()
{
    int* ptr = new int[5000];
    PtrAllocator<int> alloc = PtrAllocator<int>(ptr); //declared on a separate line :l
    std::vector<int, PtrAllocator<int>> v(alloc);
    v.resize(100);

    delete[] ptr;
}
Brandon
  • 22,723
  • 11
  • 93
  • 186

1 Answers1

1

You cannot pass a pointer, which will be dynamic in your case, as a template argument, which is static. You could pass a pointer if it were static, e.g. if you would use a globally allocated object.

What you can do is passing the pointer to pool as argument on construction as pointed out in C++ allocators, specifically passing constructor arguments to objects allocated with boost::interprocess::cached_adaptive_pool:

In C++0x, allocators should be able to call any constructor, not just the copy constructor [...]

Edit regarding your comment: The point is, an allocator allocates memory but does not initialize it. Thus you can only control e.g. memory placement or at least some basic initialization (setting 0 or whatever). To initialize memory an object has to be constructed. For this purpose you can implement construct which since C++11 accepts a range of arguments, see here, here and here. Or you can use new/delete for construction and allocation as pointed out here.

Community
  • 1
  • 1
Sebastian
  • 8,046
  • 2
  • 34
  • 58