从向量中删除元素时如何减小向量的大小?

Posted

技术标签:

【中文标题】从向量中删除元素时如何减小向量的大小?【英文标题】:How to reduce the size of vector when removing elements from it? 【发布时间】:2013-04-23 15:52:59 【问题描述】:

我正在编写一个基于输入大小限制内存的程序。假设输入大小为 1000,然后我将它们存储在大小为 1000 的向量中。稍后当我处理此向量中的数据时,每当处理完一个元素时,我将其推入我的第二个向量并使用 vector.erase从原始向量中删除它。所以我认为我总是使用 1000 大小的内存,因为这两个向量中总共存储了 1000 个元素。

但我错了,原来我使用了 2000 个内存,因为 erase 在删除元素时不会减小向量的大小...我猜 splice 也是一样的,是吗?

那么有没有办法让我的程序只使用 1000 个内存?我可以通过添加属性并标记元素是否已处理来解决它,但我觉得这不是最好的方法。谢谢!

【问题讨论】:

【参考方案1】:

这种尝试缩小容量的技术可以在 C++03 和 C++11 中使用:

std::vector<int> v;
// ...
std::vector<int>(v.begin(), v.end()).swap(v);

这个live example 包含一个演示。该技术是否有效取决于实现在使用v 的元素初始化临时向量时分配了多少内存。

在 C++11 中,可以调用成员函数 shrink_to_fit() 来执行非绑定请求,以将向量的容量缩小到容纳当前容器中的元素所需的大小。

请注意,“非约束性”表示标准不要求实现实际满足此请求。

【讨论】:

请注意,这个技巧也是不具约束力的,因为该容量可能(但可能不是)任意大,甚至比原始容量更大。是否有任何编译器实际上忽略了shrink_to_fit() 请求?我认为它过于强调它是非约束性的,所以你可能会吓跑人们使用它。 谢谢,但我试过这个方法,内存使用率似乎比以前更高...我正在用这种方法测量:/usr/bin/time -f "%Uu %MKB"在终端,有什么想法吗?【参考方案2】:

C++11 将函数 shrink_to_fit() 添加到 std::vector。如果您正在寻找一种方法来减少向量的大小,在从中删除元素之后,那将是您的选择。 Here is more information on it.

【讨论】:

谢谢,但是我试过这个方法,内存使用率似乎比以前更高...我用这种方法测量: /usr/bin/time -f "%Uu % MKB”在终端,你知道吗? 我认为潜在的问题是你创建并填充了一个新的向量,而旧的向量没有被填充。总内存影响是原始向量大小的两倍,因为您同时在删除旧向量并填充新向量。本质上,您正在复制元素,因为它们正在被访问到新向量所在的内存中的不同位置。避免这种情况的唯一方法是将每个元素标记为已处理,正如您在原始帖子中所指出的那样。 我不太明白你的意思。假设我在 old_vector 中有 1 2 3 4 5,我这样做:new_vector.push_back(old_vector[3]),然后old_vector.erase(old_vector.begin+3) 不是这些的总内存在这种情况下,2 个向量加起来总是最多 5+1 =6? 每个std::vector 在底层都由一个数组表示,当它的大小不足时会重新分配。您从大小为 1000 的old_vector 开始,然后创建new_vector,它分配在其他位置。当您从old_vector 中删除时,底层数组的大小不会改变,但会根据需要重新洗牌。然后将其添加到new_vector 的底层数组,等待重新分配。请注意,这些事情发生在两个不同的地方,这意味着无法保证即使您调整 old_vector 的大小,new_vector 也会占用已释放的空间。

以上是关于从向量中删除元素时如何减小向量的大小?的主要内容,如果未能解决你的问题,请参考以下文章

如何从向量中随机删除一个元素?

从向量中删除一个元素而不删除之后的元素

如何使用 remove_if 从向量中删除元素

如何从具有用户类参数的向量中删除元素?

分段错误:从二维向量中随机删除元素

从向量中删除取消引用的元素