减少stl向量的容量

时间:2009-07-10 18:03:48

标签: c++ stl vector

有没有办法减少矢量的容量?

我的代码将值插入到向量中(事先不知道它们的数字),以及 完成后,向量仅用于读取操作。

我想我可以创建一个新的向量,用大小和副本做一个.reseve() 这些项目,但我真的不喜欢额外的复制操作。

PS:我不关心便携式解决方案,只要它适用于gcc。

11 个答案:

答案 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)

这也有效:

Try it online!

v = std::vector<T>(v); // if we need to keep same data
v = std::vector<T>(); // if we need to clear

它调用 && 运算符的 = 重载,它进行移动,swap() 使用相同的重载。