首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >性病::病媒的容量是否会减少?

性病::病媒的容量是否会减少?
EN

Stack Overflow用户
提问于 2018-10-13 09:19:27
回答 3查看 599关注 0票数 6

C++14最终工作草案std::vector作了如下评论

存储管理是自动处理的,但提示可以提高效率。

优先选择说:

矢量的存储是自动处理的,根据需要进行扩展和压缩。

用于动态数组的Wikipedia条目说:

C++的std::vectorstd::vec::Vec是动态数组的实现

因此,我认为,当向量的容量远远大于其大小时,它的容量就会自动减少。我编写了以下代码来检查我的假设:

代码语言:javascript
运行
复制
#include <iostream>
#include <vector>

using namespace std;

int main() {
  vector<int> v = {};

  cout << "initialization" << endl;
  cout << "  capacity: " << v.capacity() << endl;
  cout << "  size: " << v.size() << endl;

  for (int i = 1; i <= 10000; i++) 
    v.push_back(i);

  cout << "after inserting a lot of elements" << endl;
  cout << "  capacity: " << v.capacity() << endl;
  cout << "  size: " << v.size() << endl;

  v.erase(v.begin() + 1, v.begin() + 10000);
  cout << "after erasing a lot of elements" << endl;
  cout << "  capacity: " << v.capacity() << endl;
  cout << "  size: " << v.size() << endl;

  v.push_back(9);

  cout << "after inserting another element" << endl;
  cout << "  capacity: " << v.capacity() << endl;
  cout << "  size: " << v.size() << endl;
}

我使用g++ -std=c++14 code.cc编译代码。运行结果的a.out将产生以下输出。我正在使用macOS Mojave。

代码语言:javascript
运行
复制
initialization
  capacity: 0
  size: 0
after inserting a lot of elements
  capacity: 16384
  size: 10000
after erasing a lot of elements
  capacity: 16384
  size: 1
after inserting another element
  capacity: 16384
  size: 2

因此,即使std::vector的容量比其大小大得多,它似乎也不会减少它的容量。

std::vector会不会减少它的容量?

那么,是否有条件触发其能力的下降呢?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2018-10-13 12:29:01

因此,我认为,当向量的容量远远大于其大小时,它的容量就应该减少。

首先,标准必须具体说明“容量远大于其规模”的含义。这将限制实现当前对重新分配策略的选择。

第二,如果减少容量,需要重新分配和移动所有剩余的元素.这意味着所有迭代器都可能被擦除无效,这限制了安全使用。

当前,擦除状态

在擦除点或之后使迭代器和引用无效,包括end()迭代器。

第三,向量在很长一段时间内保持较小的容量,同样有可能再次达到高容量水印。

对于许多有效的场景,您将使使用变得更糟,因为释放大量分配会带来令人怀疑的好处。现代虚拟内存系统可以很好地处理旧的分配,严格地说比死胡同更长。

那么,是否有条件触发其能力的下降呢?

是的,shrink_to_fit是一个明确的请求来做你想做的事情。如果你真的想把它重新分配到一个更小的大小,你可以要求它。其他可能会受到闪光灯伤害的用法不受影响。

票数 6
EN

Stack Overflow用户

发布于 2018-10-13 09:25:17

如果您的实现中的std::vector::shrink_to_fit()没有完成您想要实现的任务(因为它只是提出了一个非绑定的请求来减少向量的容量),那么您可以考虑在您的向量v上应用成语

代码语言:javascript
运行
复制
std::vector<int> v;

// ...

{
   std::vector<int> tmp(v); // create a copy of vector v
   tmp.swap(v);
   // vector tmp goes out of scope --> tmp is destroyed
}

或者仅仅是一条龙:

代码语言:javascript
运行
复制
std::vector<int>(v).swap(v);

这个成语包括创建一个由原始向量v的元素组成的临时向量对象,然后将其与原始向量v交换。

应用这个成语交换产生的临时向量和v的容量。这将导致v具有较低的容量,如果产生的临时容量低于原始向量v。如果v.size()v.capacity()低得多,情况很可能是这样的。

票数 3
EN

Stack Overflow用户

发布于 2018-10-13 09:30:08

取决于在哪种操作下。如果你把所有的都包括在内,那么是的。

参见vector.capacityp9 (shrink_to_fit):

备注:shrink_to_fit是一个非绑定请求,用于将capacity()还原为size().注意:请求是不具有约束力的,允许为特定于实现的优化提供空间。-尾注.

和vector.capacityp10 (swap):

作用:将capacity()*this的含量及x的含量进行交换。

换句话说,使用shrink_to_fit(),您可能会减少容量。使用swap(),只要您能够用较少的capacity()创建另一个vector,您就可以保证减少您的capacity() (但是请注意,“原始”容量,即现在是另一个对象的容量,其本身并没有减少)。

关于以下事项的简要说明:

因此,我认为,当向量的容量远远大于其大小时,它的容量就应该减少。我编写了以下代码来检查我的假设:

为了减少capacity(),实现需要(通常)分配内存(并移动/复制元素并释放原始存储),这是一个非常昂贵的操作,在擦除元素时没有人愿意这样做。

最重要的是,如果您的程序再次到达其新的capacity() (这很可能是因为您之前已经这样做了),则必须再次重复该过程。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/52791430

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档