Search code examples
c++memory-managementallocation

Why does shrink_to_fit (if the request is fulfilled) cause reallocation?


Given a container v with v.size() == 3 and v.capacity() == 5, my understanding is that a call to v.shrink_to_fit() can be fulfilled and, if it is, it causes v.capacity() to become 3.

However, this comes at the cost of a reallocation.

Why? Isn't it possible to free the unused memory without reallocating a chunk of memory for what remains?

Probably this question has its roots into how more primitive commands like new/delete and malloc/free work.


Solution

  • The container does not allocate/deallocate the memory on itself, but it is it's allocator who does it.

    For the (vector's) allocator to be able to deallocate the memory, it needs to be provided the exact the same pointer as the pointer to the memory it has allocated for the vector's data.

    At this is the begin of the vector data and not the begin of the "not more used" data.

    Basically, we are talking about this allocator's allocation/deallocation methods:

    pointer allocate( size_type n, const void * hint = 0 );
    void deallocate( T* p, std::size_t n );
    

    The argument T* p of the deallocate will be the same as the pointer returned from allocate ( == begin of vector's data). This is what the vector's implementation will pass to the deallocate.

    It is surely imaginable to have a custom vector implementation, who would be able to pass any pointer in range [data, data+size] to allocators deallocate method. One could construct such an allocator to be able to deal with it. But then all other allocators would need to conform to this API, also the standard allocator.

    Then something like this would need to be able to "work":

    int* p = new int[100];
    delete [] (p + 50);  // imagine making this work
    

    This would add extra complexity, performance and other issues.