【问题标题】:Changing the reserve memory of C++ vector更改 C++ 向量的保留内存
【发布时间】:2010-09-24 01:46:37
【问题描述】:

我有一个包含 1000 个“节点”的向量

 if(count + 1 > m_listItems.capacity())
     m_listItems.reserve(count + 100);

问题是当我要重新填充它时,我也将它清除了。

m_listItems.clear();

容量不变。 我使用了 resize(1);但这似乎并没有改变容量。 那么如何改变储备呢?

【问题讨论】:

  • 您的系统内存不足吗?像这样保留意味着向其中添加 n 个项目使用 O(n^2) 时间和最多 n+100 个对象的空间以及舍入误差。让向量扩展自身将减少代码、O(n) 时间,并且在大多数实现中最多使用 2*n 空间加上舍入。
  • 我的系统内存非常不足。(嵌入式).. 代码实际上只是我想实现的一个例子。在大多数情况下,我从“表”中获得 1000 个项目块,因此以相同的频率调整大小是有意义的。 CLEANUP 是我最关心的问题。

标签: c++ memory stl vector resize


【解决方案1】:
vector<Item>(m_listItems).swap(m_listItems);

将再次缩小m_listItemshttp://www.gotw.ca/gotw/054.htm(Herb Sutter)

如果你还是想清除它,用一个空向量交换:

vector<Item>().swap(m_listItems);

这当然更有效率。 (请注意,交换向量基本上意味着只是交换两个指针。没有什么真正耗时的)

【讨论】:

  • 值得指出的是,虽然 swap() 非常便宜,但在第一种情况下构造 m_listItems 的临时副本将需要复制向量中的每个元素。因此,虽然完全清除向量(将容量设置为 0)很便宜。否则不会缩小规模。
  • 确实是jalf。但是如果 vector 本身有一个 shrink() 函数,那么这个序列基本上是相同的。无论如何都需要重新分配:/
  • 但是你的观点很好,因为在 c++1x 中,向量可以将它们的元素移动到新的位置。我的代码应该看起来很简单 vector(std::move(m_listItems)).swap(m_listItems);那我想
  • 我正在寻找清晰的.. 并没有真正缩小尺寸。我使用向量作为填充列表的工具。老实说,我认为它是通过链表实现的。看来我错了。哦,现在已经够快了。
  • @litb:移动它可能不起作用,因为结果将与以下内容相同:m_listItems.swap(m_listItems);这是一个空操作。
【解决方案2】:

您可以按照其他人的建议交换矢量,并且如 http://www.gotw.ca/gotw/054.htm 中所述,但请注意它不是免费的,您正在执行每个元素的副本,因为矢量有分配一个新的、更小的内存块,并复制所有旧内容。 (交换操作本质上是免费的,但您正在与一个用原始向量数据的副本初始化的临时进行交换,这不是免费的)

如果您事先知道向量有多大,则应从一开始就分配正确的大小,因此无需调整大小:

std::vector<foo> v(1000); // Create a vector with capacity for 1000 elements

如果你事先不知道容量,那浪费一点空间又有什么关系呢?是否值得花时间将每个元素复制到一个新的更小的向量(这就是 std::vector(v).swap(v) 将做的),只是为了节省几千字节的内存?

同样,当您清除矢量时,如果您打算重新填充它无论如何,将其容量设置为零似乎是一种令人印象深刻的浪费时间。

编辑

baash05: 如果你有 1000000 个项目怎么办 10 兆公羊。你可以说 减少开销是 重要吗?

没有。调整矢量的大小暂时需要更多内存,因此如果您的内存有限,这可能会破坏您的应用程序。 (在交换它们之前,您必须将原始向量保存在内存中, 是临时的,因此您最终会使用最多两倍的 RAM)。之后,您可能会节省少量内存(最多几 MB),但这没关系,因为向量中的多余容量永远不会被访问,所以它会被推送到页面文件,所以不会首先计入您的 RAM 限制。

如果您有 1000000 个项目,那么您应该首先将向量初始化为正确的大小

如果你不能做到这一点,那么你通常最好不要管这个容量。尤其是既然你说要重新填充向量,你绝对应该重用已经分配的容量,而不是不断地分配、重新分配、复制和释放所有东西。

您有两种可能的情况。您要么知道需要存储多少元素,要么不知道。如果您知道,那么您可以首先创建具有正确大小的向量,因此您永远不需要调整它的大小,或者您不知道,然后您还不如保留多余的容量,所以至少它重新填充矢量时不必向上调整大小。

【讨论】:

  • 如果您有 1000000 件物品和 10 兆公羊会怎样。您认为减少开销很重要吗?
【解决方案3】:

你可以从here试试这个技巧

std::vector< int > v;
// ... fill v with stuff...
std::vector< int >().swap( v );

【讨论】:

    【解决方案4】:

    您可以使用具有所需容量的新向量 swap 它。

    vector< int > tmp;
    old.swap( tmp );
    

    【讨论】:

      【解决方案5】:

      据我所知,您不能将向量重新分配到比以往更低的容量;你只能分配更大的。这有充分的理由;其中之一是重新分配过程的计算量非常大。如果你真的需要一个更小的向量,释放旧的并创建一个更小的新向量。这实际上在计算上比将向量实际调整为更小要简单得多。

      【讨论】:

      • 取决于它是如何分配的——要么让它超出范围,要么调用删除。与交换相比,我认为这不是一个好的建议。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-03-15
      • 2011-01-30
      • 1970-01-01
      • 1970-01-01
      • 2018-10-23
      • 1970-01-01
      相关资源
      最近更新 更多