简体   繁体   中英

Implementing a simple allocator class using malloc() and free()

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM