Does std::vector.pop_back() change vector's capacity?
Asked Answered
K

6

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?

Kunzite answered 8/10, 2009 at 9:52 Comment(0)
F
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().

Fructification answered 8/10, 2009 at 9:57 Comment(4)
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.Stentor
@einpoklum: Yeah, this is without moving, and thus suboptimal today. But this answer is almost a decade old, so...Fructification
@sbi: I would advise against it then as well :-(Stentor
@einpoklum: So you would, huh? Well, the C++ community thought otherwise back then. So go figure.Fructification
S
4

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

Swiftlet answered 8/10, 2009 at 9:57 Comment(1)
Duplicate of @sbi's answer; and see my comment there about the "swap trick".Stentor
H
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(); 

}
Huffish answered 26/11, 2015 at 11:40 Comment(0)
O
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().

Ordinate answered 8/10, 2009 at 10:5 Comment(0)
I
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.

Incorporate answered 9/10, 2009 at 2:39 Comment(0)
A
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.

Alvinaalvine answered 13/4, 2013 at 17:56 Comment(1)
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.Bouley

© 2022 - 2024 — McMap. All rights reserved.