Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/140.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
pop_back()能减少向量的容量吗?(C+;+;) 根据C++标准,是 STD::vector:POPYBACK()/允许减少向量的容量吗?< /P>_C++_C++11_Vector_Capacity - Fatal编程技术网

pop_back()能减少向量的容量吗?(C+;+;) 根据C++标准,是 STD::vector:POPYBACK()/允许减少向量的容量吗?< /P>

pop_back()能减少向量的容量吗?(C+;+;) 根据C++标准,是 STD::vector:POPYBACK()/允许减少向量的容量吗?< /P>,c++,c++11,vector,capacity,C++,C++11,Vector,Capacity,我之所以这样问是因为我想保证以下代码不会抛出内存不足异常: my_vec.pop_back(); if (...) my_vec.push_back(...); 假设my_vec是一个std::vector 我想有三种可能: 是的,这可以根据C++03和C++11实现 不,C++11禁止这样做(但C++03不禁止) 不,C++03和C++11都禁止这样做 是的,我的问题与此相关,但我的问题具体是关于标准保证的内容 还要注意的是,中被接受的答案主要是关于如何减少向量的容量,而不是关于何时

我之所以这样问是因为我想保证以下代码不会抛出内存不足异常:

my_vec.pop_back();
if (...)
    my_vec.push_back(...);
假设
my_vec
是一个
std::vector

我想有三种可能:

  • 是的,这可以根据C++03和C++11实现

  • 不,C++11禁止这样做(但C++03不禁止)

  • 不,C++03和C++11都禁止这样做

  • 是的,我的问题与此相关,但我的问题具体是关于标准保证的内容

    还要注意的是,中被接受的答案主要是关于如何减少向量的容量,而不是关于何时保证它不会发生,并且没有提供任何证据证明它关于pop_back()的说法。

    除了
    back()
    end()
    之外,没有任何迭代器或引用无效

    因此,它可能不会重新分配。该页面上没有
    C++11
    标记,这意味着03中也是如此。为了完整起见,我将挖掘章节参考资料并对其进行编辑

    编辑:甚至更好:来自
    C++03
    :[lib.container.requirements](23.1),第10段:

    erase()
    pop_-back()
    pop_-front()
    函数引发异常


    N3337中23.2.1/10的措辞相同(~
    C++11
    )。

    否。缩小向量容量的唯一方法是交换技巧,如图所示。还有我下面提到的
    C++11
    方式

    此外,正如《基本法》所说:

    删除向量中的最后一个元素,
    有效地将容器大小减少一个

    换句话说,它改变向量的大小,而容量

    看看迭代器的有效性:

    结束迭代器和任何迭代器、指针和引用
    引用已删除的元素无效。
    引用其他对象的迭代器、指针和引用
    未删除的元素保证保持
    指的是他们在通话前所指的相同元素

    C++11
    中,可以使用
    std::vector::shrink_to_fit()
    来更改容量(有关更多信息,请参阅第1个链接)。(tnx Psyduck)。答案下面有有趣的评论,但这个问题与上述方法无关,因此如果感兴趣,请阅读评论

    请注意,即使这种方法也不能保证减少
    容量
    ,如下所示:

    请求容器减小其容量以适应其大小

    请求是非绑定的,容器实现可以自由地进行优化>,并使向量的容量大于其大小

    这可能会导致重新分配,但对向量大小没有影响,并且无法更改其>元素

    太奇怪了,这个函数不能保证减少
    容量
    返回
    ,而第二个函数的ref没有提到任何相关的内容

    在我看来,由于ref没有提到容量,这意味着不需要,也就是说容量保持不变

    一个有趣的例子是:

    #include <iostream>
    #include <vector>
    
    int main() {
      const int N = 1000000;
    
      std::vector<int> v1;
      v1.reserve(N);
      for (int i = 0; i < N; ++i) {
        v1.push_back(i);
      }
    
      std::cout << v1.capacity() << " and size = " << v1.size() << std::endl;
    
      for (int i = 0; i < N - 2; ++i) {
        v1.pop_back();
      }
    
      std::cout << v1.capacity() << " and size = " << v1.size() << std::endl;
    
      return 0;
    }
    
    其中,
    容量
    明显未减少

    [编辑]

    另一个相关的,也可以标记为重复的,有一些很好的答案。以下是一些有趣的例子:

    (一)

    去看Scott Meyers有效STL第17项。(OP看起来有一些参考) 基本上,您不能直接减少std::vector的存储大小。“技巧”是>创建一个大小合适的新容器,复制数据并与当前容器交换

    (二)

    不,如果不进行复制,则无法减少向量的容量

    (三)

    我并不是说GCC在没有副本的情况下不能有一些方法来做你想做的事情,>但是实现起来很困难(我认为),因为向量需要使用分配器对象来分配和释放内存,分配器的接口不包括reallocation()方法。我不认为这是不可能的,但这可能是棘手的

    我建议阅读更多链接

    [编辑.2]

    这也支持:

    问:
    pop_back()
    是否可以减少
    容量

    答:


    当你不能依靠适当的方法来降低容量时(根据你在标准中所读到的内容),你就不能指望
    pop_back()
    会做这样的事情。

    评论并没有真正解决这个问题。显然,如果std::vector禁止使用std::allocator之外的任何东西,并且如果std::allocator禁止使用其他方法进行扩展,那么就不可能使用相同的基址调整大小,这就不可能降低容量,因为迭代器将失效

    我能找到的关于再分配的最接近的信息是stackoverflow评论说

    “在某些情况下,没有任何东西可以阻止std::vector这样做(例如,它知道它在使用标准分配器)。允许标准库使用底层系统的知识。-KeithB Jun 23'10于21:39(但未提及参考文献)

    已经提交了将realloc添加到std::allocator的想法,但都被拒绝:

    不过,论文并没有明确指出std::allocator禁止扩展std::allocator,他们只是说它不需要扩展。它们也没有明确声明禁止std::vector使用对底层系统的API调用。。。所以没有真实的信息
    1000000 and size = 1000000
    1000000 and size = 2