【问题标题】:How to downsize std::vector?如何缩小 std::vector 的大小?
【发布时间】:2010-09-20 04:05:09
【问题描述】:

当我不再需要以前保留的空间时,有没有办法调整 std::vector 的大小以降低容量?

【问题讨论】:

    标签: c++ stl vector


    【解决方案1】:

    Effective STL,Scott Meyers,第 17 条:使用swap 技巧来削减过剩产能。

    vector<Person>(persons).swap(persons);
    

    之后,persons 被“缩小以适应”。

    这依赖于 vector 的复制构造函数仅分配被复制元素所需的内存。

    【讨论】:

    • 建议修正语法:'shrunk',而不是 'shrinked'
    • 不错。您可能知道为什么他们没有将其作为一种方法来实现,因为它看起来是容器的常见用例?
    • 一旦向量分配了一个缓冲区,就很难删除[]该缓冲区的末尾。这样做只是保证未来的插入将需要分配一个新的缓冲区并将所有内容复制到它(使迭代器无效)。
    【解决方案2】:

    如果您使用的是 C++11,则可以使用 vec.shrink_to_fit()。至少在 VS2010 中,这对你来说是交换技巧。

    【讨论】:

    • 它不等同于交换技巧。 shrink_to_fit 是一个非绑定请求,允许不做任何事情。
    • 我说“在 VS2010 中”但是是的,在其他编译器上它可能不会这样做。
    • @CatPlusPlus shrink_to_fit 很可能会使用交换技巧或realloc,但会进行小的向量优化,但仍然不会重置capacity() 以匹配size(),因为没有堆分配收缩。我认为这就是它被指定为“非约束性”的原因。
    【解决方案3】:

    从现有向量创建一个新的临时向量,然后在现有向量上调用 swap 方法,将临时向量传入。让临时向量(现在带有旧的、过大的缓冲区)超出范围。

    嘿,presto,你的向量的大小正好适合它的内容。

    如果这听起来像很多复制和分配 - 请记住,这就是向量每次必须重新分配超过其当前保留限制时所做的事情。

    [编辑] 是的,我只是说和塞巴斯蒂安一样的话。 stackoverflow 竞争条件的另一种情况;-)

    【讨论】:

    • 好吧,我对你投了赞成票,菲尔因为即使你不是第一个发帖的人,你的回答仍然很有帮助! :-)
    【解决方案4】:

    交换技巧是减少对象容量的有效方法, 它通过复制构造将我的向量的内容与新创建的向量交换:

    vector<Person>(persons).swap(persons);
    

    请注意,不保证 person.capacity();在交换技巧等于 大小:vector(persons) 的容量是库实现的容量 保留大小为 person.size() 的向量。

    C++11 引入shrink_to_fit().

    shrink_to_fit() 以及交换技巧并不能保证容量大小是有效的 减小到向量的大小。

    无论如何,shrink_to_fit() 可以使您的迭代器无效(如果发生重新分配)或不能: 这取决于库的实际实现。

    请记住,交换技巧需要 Person.size() 复制 Person 和 person.size() 破坏。 shrink_to_fit() 可以避免所有这些复制,并且可以 让你的迭代器有效。可以。但有时会发生 shrink_to_fit() 在 交换技巧的条款...

    【讨论】:

    • 您能否指出在哪里指定shrink_to_fit() 必须以swap() 的形式实现?
    • @TobySpeight 感谢您的评论。也许我的英语不够好。我的意思是,既然 shrink_to_fit() 可以根据交换技巧来实现,那么有时它就是以这种方式实现的。让我编辑答案。如果我没有成功,请随时编辑答案以提高其质量。您的贡献将受到欢迎。谢谢
    【解决方案5】:

    您正在寻找 QVector::squeeze 的等价物,恐怕它在 STL 中并不明确存在。 如果 Sébastien 的答案对您的 STL 实现是正确的,请寻求它。

    【讨论】:

      猜你喜欢
      • 2012-07-04
      • 1970-01-01
      • 1970-01-01
      • 2012-07-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多