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;
}
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With