删除std :: vector的元素(并更改大小),而不会影响已分配的内存

时间:2013-06-16 15:36:33

标签: c++ memory stdvector

我正在使用以下代码:

const int MY_SIZE = 100000;
std::vector<double> v;
v.reserve(MY_SIZE);

// add no more than MY_SIZE elements to the vector

f(v);    
v.clear();

// again, add no more than MY_SIZE elements to the vector

f(v);
v.clear();

//
// etc...
//

我的代码的重点是存储MY_SIZE double,然后对这些元素执行操作f(std::vector<double>)。在我填充向量并执行操作之后,我想摆脱所有元素(并将std::vector::size()重置为0),然后添加更多元素。但是,这里的关键是我想要导致为向量分配的内存空间被更改。

请注意,我永远不会向MY_SIZE添加超过v个元素,因此v永远不需要重新分配比v.reserve(MY_SIZE)分配的内存更多的内存。

所以,当我在上面的代码中调用v.clear()时,它会以任何方式影响v.reserve(MY_SIZE)分配的空间量或v.begin()内存中的位置吗?


相关问题:如果我致电v.erase(v.begin(),v.begin()+v.size()),它会以任何方式影响v.reserve(MY_SIZE)分配的空间量或v.begin()内存中的位置?

如果我真的只想删除所有元素,我会打电话给clear()。但是我想知道这个相关的问题,因为有时候我只需要擦除v的前X个元素,并且在这些情况下我想保留由v.reserve(MY_SIZE)分配的内存而且我不要不希望v的位置发生变化。

1 个答案:

答案 0 :(得分:1)

如果你调用clear()的{​​{1}}或erase()方法,C ++标准(2003)似乎隐含地保证不重新分配内存。

根据序列的要求(表67),std::vector相当于a.clear()

此外,该标准规定a.erase(begin(),end())的{​​{1}}成员函数不会抛出异常,除非T的复制构造函数抛出一个(第23.2.4.3节)。因此,它是隐式保证的,因为重新分配可能导致异常(第3.7.3节,第20.4.1.1节)。

同样erase(...)保持不变,因为std::vector<T>只会在擦除点之后使所有迭代器无效(第23.2.4.3节)。但是,它不会被解除引用(因为v.begin())。

所以,如果你有一个符合标准的实现,你就可以了......

<强> CORRECTION

我的推理存在缺陷。我设法显示erase(...)没有重新分配,但是如果删除所有元素,实现仍然可以释放内存。但是,如果v.begin() == v.end()报告“你可以在擦除/清除后添加N个元素而不重新分配内存”,那么你没事。

C ++ 11标准定义了erase(...)而没有引用a.capacity()a.clear()不允许抛出异常。因此它可以解除分配,但不能重新分配。因此,您应该在清除向量后检查容量,以确保内存仍然存在,并且下一次调整大小将不会重新分配。