有没有办法减少矢量的容量?
我的代码将值插入到向量中(事先不知道它们的数字),以及 完成后,向量仅用于读取操作。
我想我可以创建一个新的向量,用大小和副本做一个.reseve() 这些项目,但我真的不喜欢额外的复制操作。
PS:我不关心便携式解决方案,只要它适用于gcc。
答案 0 :(得分:39)
std::vector<T>(v).swap(v);
用另一个向量交换内容交换容量。
std::vector<T>(v).swap(v); ==> is equivalent to
std::vector<T> tmp(v); // copy elements into a temporary vector
v.swap(tmp); // swap internal vector data
Swap()只会改变内部数据结构。
答案 1 :(得分:35)
使用C ++ 11,您可以调用成员函数shrink_to_fit()
。 draft standard部分23.2.6.2说:
shrink_to_fit
是一个非约束性请求 将capacity()
缩减为size()
。 [注意:请求不绑定 允许纬度 特定于实现的优化。 - 尾注]
答案 2 :(得分:14)
去看看Scott Meyers Effective STL第17项。
基本上,您不能直接减少std::vector
的存储空间。 resize()
和reseve()
永远不会减少容器的实际内存占用量。 “技巧”是创建一个合适大小的新容器,复制数据并与当前容器交换。如果我们想清除一个容器,这只是:
std::vector<T>().swap(v);
如果我们必须复制数据,那么我们需要复制:
std::vector<T>(v).swap(v);
这样做会创建一个带有旧数据的新向量,执行任何具有所需效果的操作所需的副本。然后调用swap()
将只交换对象之间的内部缓冲区。在该行的末尾,删除了创建的临时矢量,但它具有来自旧矢量的内容,而旧矢量具有来自新副本的内容,这是我们需要的确切大小。
答案 3 :(得分:6)
惯用解决方案是与新构造的矢量交换。
vector<int>().swap(v);
编辑:我误解了这个问题。上面的代码将清除向量。 OP希望保持元素不变,只将capacity()
缩小为size()
。
很难说aJ的代码是否会这样做。我怀疑是否有便携式解决方案。对于gcc
,您必须查看其vector
的特定实现。
编辑:所以我偷看了libstdc ++实现。似乎aJ的解决方案确实有效。
vector<int>(v).swap(v);
见the source,第232行。
答案 4 :(得分:3)
不,你不能在没有复制的情况下减少矢量的容量。但是,您可以通过每次插入内容时检查capacity()和调用reserve()来控制新的分配增长量。 std :: vector的默认行为是每次需要新容量时将其容量增加2倍。你可以用你自己的魔法比率来增长它:
template <typename T>
void myPushBack(std::vector<T>& vec, const T& val) {
if (vac.size() + 1 == vac.capacity()) {
vac.reserve(vac.size() * my_magic_ratio);
}
vec.push_back(val);
}
如果你有点hacky技术,你总是可以传入你自己的分配器,并做你需要做的任何事情来回收未使用的容量。
答案 5 :(得分:2)
我不是说GCC没有一些方法可以在没有副本的情况下做你想做的事情,但实现起来很棘手(我认为)因为向量需要使用Allocator
对象来分配并释放内存,Allocator
的接口不包含reallocate()
方法。我不认为这是不可能的,但它可能会很棘手。
答案 6 :(得分:1)
如果你担心矢量的开销,那么你应该考虑使用其他类型的数据结构。您提到,一旦您的代码完成初始化向量,它就变成了只读进程。我建议使用开放式数组,这将允许程序在编译时决定其容量。或者链表可能更适合您的需求 Lemme知道我是否完全误解了你的目标。
-UBcse
答案 7 :(得分:1)
旧线程,我知道,但是如果有人在将来查看这个...在C ++ 11中有shrink_to_fit()但由于它是一个非绑定请求,行为将取决于它的实现。
请参阅:http://en.cppreference.com/w/cpp/container/vector/shrink_to_fit
答案 8 :(得分:0)
获取Scott Myers的“Effective STL”一书。它有一个关于减少矢量容量的完整项目。
答案 9 :(得分:0)
我不是C ++专家,但似乎this解决方案有效(至少可以使用g ++进行编译):
std::vector<int>some_vector(20);//initial capacity 10
//first you gotta resize the vector;
some_vector.resize(10);
//then you can shrink to fit;
some_vector.shrink_to_fit();
//new capacity is 10;
答案 10 :(得分:0)
这也有效:
v = std::vector<T>(v); // if we need to keep same data
v = std::vector<T>(); // if we need to clear
它调用 &&
运算符的 =
重载,它进行移动,swap() 使用相同的重载。