15

If I allocated an std::vector to a certain size and capacity using resize() and reserve() at the beginning of my program, is it possible that pop_back() may "break" the reserved capacity and cause reallocations?

unwind
  • 391,730
  • 64
  • 469
  • 606
jackhab
  • 17,128
  • 37
  • 99
  • 136

6 Answers6

19

No. The only way to shrink a vector's capacity is the swap trick

template< typename T, class Allocator >
void shrink_capacity(std::vector<T,Allocator>& v)
{
   std::vector<T,Allocator>(v.begin(),v.end()).swap(v);
}

and even that isn't guaranteed to work according to the standard. (Although it's hard to imagine an implementation where it wouldn't work.)

As far as I know, the next version of the C++ standard (what used to be C++0x, but now became C++1x) will have std::vector<>::shrink_to_fit().

sbi
  • 219,715
  • 46
  • 258
  • 445
  • 1
    I would very much advise against this trick for three reasons: 1. Function doesn't necessarily do what it says it does. 2 Breaks the principle of "least surprise" 3. Incurs a huge amount of overhead, potentially - not to mention potential side-effects of copying rather than moving. – einpoklum Feb 10 '18 at 16:11
  • @einpoklum: Yeah, this is without moving, and thus suboptimal today. But this answer is almost a decade old, so... – sbi Feb 10 '18 at 16:27
  • @sbi: I would advise against it then as well :-( – einpoklum Feb 10 '18 at 16:29
  • @einpoklum: So you would, huh? Well, the C++ community thought otherwise back then. So go figure. – sbi Feb 11 '18 at 19:01
4

No. pop_back() will not shrink the capacity of vector. use std::vector<T>(v).swap(v) instead.

aJ.
  • 34,624
  • 22
  • 86
  • 128
4

Under C++11 one can call shrink_to_fit() to ask for a vector (as well as a deque or a string) in order to reduce the reserved space to the vector's capacity. Note however that this is implementation dependent: it's merely a request and there's no guarantee whatsoever. You can try the following code:

#include <iostream>
#include <vector>
using namespace std;

int main(){
    vector<int> myVector;

    for (auto i=1;i!=1e3;++i)
        myVector.push_back(i);

    cout << "Capacity: " << myVector.capacity() << endl;
    myVector.reserve(2000);
    cout << "Capacity (after reserving 2000): " << myVector.capacity() << endl;
    myVector.shrink_to_fit();
    cout << "Capacity (after shrink_to_fit): " << myVector.capacity(); 

}
2

NO. Same as push_back , pop_back won't impact the capacity(). They just impact the size().

EDIT:

I should have said push_back won't change the capacity when the v.size() < v.capacity().

pierrotlefou
  • 39,805
  • 37
  • 135
  • 175
2

pop_XXX will never change the capacity. push_XXX can change the capacity if you try to push more stuff on than the capacity allows.

Zanson
  • 3,991
  • 25
  • 31
1

Here is the code of std::vector::pop_back()

void pop_back()
{   // erase element at end
   if (!empty())
   {    // erase last element
      _Dest_val(this->_Alval, this->_Mylast - 1);
      --this->_Mylast;
   }
}

Function only calls the Destructor and decreases pointer to the last element. Code from VC (Release). So it does not affect on capacity (or reallocation) of vector.

Vladimir Ivanov
  • 147
  • 1
  • 4
  • 2
    One particular implementation isn't enough information to determine what the standard requires. And this may not be the same implementation that the person asking the question uses. – Adrian McCarthy May 20 '14 at 16:37