std::vector.pop_back()会改变向量(vector)的容量吗?

15

如果我在程序开始时使用 resize()reserve() 分配了特定大小和容量的 std::vector,那么是否有可能 pop_back() 会“破坏”保留的容量并导致重新分配?

6个回答

19

不行。缩小向量容量的唯一方法是使用交换技巧。

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

甚至按照标准来说,也不能保证它能够正常工作。(虽然很难想象它不工作的情况。)

据我所知,下一个版本的C++标准(曾经的C++0x,现在成为C++1x)将拥有std::vector<>::shrink_to_fit()函数。


1
我非常建议不要使用这个技巧,原因有三:1.函数不一定做它所说的事情。2.违反了“最小惊讶原则”。3.会产生巨大的开销,可能还会带来复制而不是移动的潜在副作用。 - einpoklum
@einpoklum:是的,这是不移动的,因此今天并不是最佳选择。但是这个答案已经有将近十年的历史了,所以... - sbi
@sbi:我也建议不要这样做 :-( - einpoklum
@einpoklum:那你会这样做吗?嗯,C++社区当时持有不同的看法。所以你自己想吧。 - sbi

4

在C++11中,可以调用shrink_to_fit()方法来请求将vector(以及deque或string)的保留空间减少到其容量。然而,请注意这是与实现相关的:它仅仅是一个请求,并没有任何保证。您可以尝试以下代码:

#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(); 

}

4

不,pop_back() 不会减小 vector 的容量。可以使用 std::vector<T>(v).swap(v) 来实现。


@sbi的答案的副本;请看我在那里关于“交换技巧”的评论。 - einpoklum

2

pop_XXX不会改变容量。如果你试图推入超过容量限制的内容,push_XXX可以改变容量。


2

不会。与push_back相同,pop_back不会影响capacity(),它们只会影响size()

编辑:

v.size() < v.capacity()时,我应该说push_back不会改变容量。


1

这是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;
   }
}

该函数只调用析构函数并将指针减少到最后一个元素。来自VC(Release)的代码。因此,它不会影响向量的容量(或重新分配)。


2
一种特定的实现并不足以确定标准要求。而且这可能不是提问者使用的相同实现。 - Adrian McCarthy

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接