Search code examples
c++memory-managementvectorreallocallocator

How do I use use std::allocator in place of realloc?


Let's say I'm writing a custom vector using the std::allocator to wrap new and delete.

When the number of elements exceed the vector's capacity, I would like to reallocate the buffer to something larger. I can achieve this easily by calling realloc(). I don't want to do this though because I thought the responsibility of allocation/deallocation should reside in the allocator.

Yet, looking at std::allocator's interface, I don't see how I could do a reallocation. There are only methods for:

T* allocate( std::size_t n );
void deallocate( T* p, std::size_t n );

Should I be calling allocator::allocate and then allocator::deallocate instead of just realloc? Is that as efficient? It must be what std::vector is doing as well. Why does std::allocator not provide a reallocate function?


Solution

  • Let's say I'm writing a custom vector using the std::allocator to wrap new and delete.

    In the general case (excluding specializations for PODs), I don't think you could use realloc in any case. An arbitrary object, constructed at a specific memory location, might have internal pointers pointing to very specific addresses in relation to the address in which it was constructed. Simply moving it around (in the byte-copying sense) could break invariants.

    Thus the alternative you mention is in general necessary. You would have to allocate a new array, move (or possibly even copy!) the objects to the new location, then deallocate the old array. Of course, this includes more than a single stage that can fail - another reason why you can't really reallocate in the general case. Perhaps this is the reason that allocators never had this functionality in the first case - for array-based containers, you can't really use them in general (although you might be able to use them for POD specializations).