4

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?

Trevor Hickey
  • 36,288
  • 32
  • 162
  • 271
  • 1
    _"Why does std::allocator not provide a reallocate function?"_ This is covered somewhat in [this question](http://stackoverflow.com/questions/3105001/why-is-there-no-reallocation-functionality-in-c-allocators?rq=1). – sjrowlinson Aug 02 '16 at 17:12
  • [FYI] https://isocpp.org/wiki/faq/freestore-mgmt#realloc-and-renew – NathanOliver Aug 02 '16 at 17:16
  • 1
    @NathanOliver It ends by stating "In C++, a better way of dealing with reallocation is to use a standard library container, such as vector, and let it grow naturally.", which is the starting point of this question... – Ami Tavory Aug 02 '16 at 17:24
  • @AmiTavory And round and round it goes ;) Just pointing out to the OP that mixing new and realloc is not a good idea. – NathanOliver Aug 02 '16 at 17:26
  • @NathanOliver You have a point, and the comment is indeed pertinent. Sorry if I mistakenly gave the impression I thought it wasn't. – Ami Tavory Aug 02 '16 at 17:34
  • No problem. The ... at the end made me think there was something wrong with it. No worries though. – NathanOliver Aug 02 '16 at 17:35
  • It’s worth pointing out that while `realloc` operates on a lower level than, say, `std::vector`’s capacity, they both do fundamentally the same thing, and implementing reallocation yourself using a combination of `allocate`, `deallocate` and moving should be expected to be just as efficient (probably more efficient in general, since we can provide hints in the form of a capacity): `realloc` isn’t performing magic, after all. – Konrad Rudolph Aug 02 '16 at 17:51

1 Answers1

4

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).

Ami Tavory
  • 74,578
  • 11
  • 141
  • 185