使std :: vector容量> = N且size = 0的最佳方法?

时间:2018-07-05 08:39:37

标签: c++ vector std stdvector

考虑到p <- plot_ly(grph$try1, x = ~Inputs, y = ~Inputs2, type = 'bar', text = ~round(Inputs2, 2), textposition = 'auto', name = 'Inputs2', marker = list(color = 'rgb(204,204,204)')) %>% add_trace(y = ~Inputs3, text = ~round(Inputs3, 2), textposition = 'auto', name = 'Inputs3', marker = list(color = 'rgb(49,130,189)')) %>% layout(title = "Plot", barmode = 'group', yaxis = list(title = "Count")) 的大小和容量可以是任意的,将其大小更改为0并将容量至少更改为N(给定数字)的最佳实践是什么?

我的直接想法是:

std::vector

但是我注意到了

  

不能保证会发生重新分配,向量容量为   不保证更改(调用std::vector::clear时)。

所以我想知道当原始容量大于给定N时如何避免重新分配?

3 个答案:

答案 0 :(得分:4)

  

什么是将其大小更改为0并将容量更改为N(给定数字)的最佳实践?我的直接想法是:...

您的直接想法是正确的,也是最简单的选择。尽管reserve有点古怪,但将容量更改为更大或等于给定的数字;不能保证相等(但是如果以前的容量较小,我测试过的所有实现都确实会分配给定的数量)。

  

所以我想知道当原始容量大于给定N时如何避免重新分配?

通过使用已选择在调用clear时不释放内存的标准库实现(即,任何符合标准的实现,如答案here所示)。


另一种保证方法(尽管看起来很必要,尽管cplusplus.com上的措词很弱,但上述保证没有必要)没有重新分配(在N > t.capacity()情况下):由于向量包含简单的整数,并且您似乎知道有多少个元素(如您所知要保留),您可以简单地调用t.resize(N)(在大小较大的情况下删除多余的元素)而无需清除向量,然后继续覆盖现有元素,而不是推送新元素。

当然,这意味着您将无法观察已被覆盖的元素数量,因此该方法不适用于所有用例。如果只想用一个简单的循环填充向量就可以了。

如果新大小可能大于旧大小,并且您希望不过度分配,则可能需要在调整大小之前保留。这是因为大多数实现都在储备中分配了准确的数量(如我所述),但在调整大小时使用了乘法策略(就我所知,这些行为都不能保证,但是我使用的实现与这种行为是一致的)。 / p>

答案 1 :(得分:3)

最好的方法可能是您当前的代码。

不幸的是,该标准允许实现只具有容量只能增长的容器。在这种情况下,您的代码将仅保证容量为至少N。如果初始容量小于N,则将发生重新分配,而如果容量大于N,则将不会发生任何事情。之所以采用该标准,是因为C ++ 17的草案4659在[vector.capacity](强调我的)上表示:

  

void reserve(size_type n);
...
  3效果:一条指令,该指令将向量的计划大小更改通知向量,以便它可以管理存储   相应地分配。 在reserve()之后,capacity()大于或等于reserve的参数,如果   重新分配发生;并等于以前的Capacity()值。重新分配发生   此时且仅当当前容量小于reserve()的参数时。

  

void shrink_to_fit();
...
  8效果:shrink_to_fit是无约束请求,用于将Capacity()减小为size()。 [注意:要求   是不具有约束力的,以允许进行特定于实现的优化。 —尾注]它没有   增加Capacity(),但可能通过引起重新分配来减少Capacity()。

您无法保证容量恰好为N。相反,您的代码保证,如果初始容量大于N in,则将保持不变,并且不会发生重新分配。

编辑:至少从C ++ 11起(n3337草稿),此行为是稳定的

答案 2 :(得分:0)

注意:此答案回答了以下问题:

  

制作std :: vector容量= N且尺寸= 0的最佳方法是什么?

  

将大小更改为0,将容量更改为N(给定数字)的最佳做法是什么?

发布此答案后,添加了对“> = N”的更改以及避免重新分配的附加要求。


该标准没有提供任何保证的方法来实现这一目标。但是您最好的机会是:

 t.clear();
 t.shrink_to_fit();
 t.reserve(N);

建议第二次调用,以减少与当前大小(此时为0)相匹配的容量。

再次取决于实施情况的选择,可能有效或无效的一种替代方法是:

t.swap( std::vector<int>{} );
t.reserve(N);