Is this simple implementation of an allocator acceptable
template<typename T>
class Allocator
{
public:
T * allocate(int n); //allocate space for n objects of type T
void deallocate(T* p, int n); //deallocate n objects of type T starting at p
void construct(T* p, const T& v); //construct a T with the value v in p
void destroy(T* p); //destroy the T in p
};
template<typename T>
T* Allocator<T>::allocate(int n)
{
T* new_mem = (T*)malloc(n * sizeof(T));
return new_mem;
}
template<typename T>
void Allocator<T>::construct(T* p, const T& v)
{
T* constructed_object = new(p) T{ v };
}
template<typename T>
void Allocator<T>::deallocate(T* p, int n)
{
for (int i = 0; i < n; ++i)
{
free(&p[i]);
}
}
template<typename T>
void Allocator<T>::destroy(T* p)
{
p->~T();
}
I'm to use it in a vector to implement function that reserves exra space as follows:
template<typename T, typename A>
void vector<T, A>::reserve(int newalloc)
{
if (newalloc <= space)return;
T* p = alloc.allocate(newalloc);
for (int i = 0; i < sz; ++i)alloc.construct(&p[i], elem[i]);
for (int i = 0; i < sz; ++i)alloc.destroy(&elem[i]);
elem = p;
space = newalloc;
}
where typename A = Allocator<T>
and alloc
is of type A
. Will the allocator class I implemented be functional enough to work? (I feel the deallocate
function is suspect)
Your deallocation function is indeed incorrect. The rules for free
and malloc
is simple: you must pass exactly the pointers you got from malloc
to free
.
template<typename T>
void Allocator<T>::deallocate(T* p, size_t)
{
free(p);
}
Note you should in general pass the same pointer type to deallocation functions as well, but in this case since free
only takes void*
as parameter, the implicit conversion will take care of that.
No, this isn't going to work.
You ought to have a rebind
method.
You need to provide comparison operators ( ==
and !=
)
Your allocate
method allocates too much. By the time it gets to you, the sizeof(T)
has already happened.
Your deallocate
method is just wrong. You get a single pointer. The second parameter is a hint to the size of the allocation.
The construct
and destruct
methods are optional. If you don't provide them, they will be synthesized for you by allocator_traits
.
See https://github.com/llvm-mirror/libcxx/blob/5a424a985612452d4f7a3f02422207456d54a53e/test/support/min_allocator.h#L21 for an example of a minimal allocator (albeit w/oa rebind
)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.