我找到了一个为STL Vectors
尝试的示例程序#include <vector>
#include <iostream>
using namespace std;
/* This one may well work with some compilers/OS, and crash with
others. Who said the STL was safe ?? */
int main() {
vector<int> v;
v.push_back(1);
v.push_back(2);
v.push_back(3);
v.push_back(4);
for (vector<int>::iterator i = v.begin();
i != v.end(); i++) {
cout << *i << endl;
if (*i == 1) {
v.push_back(5);
}
}
}
我期待的结果:1 2 3 4 5
但是,结果非常奇怪 - 1 0 3 4 0 0 33 0 0 0 0 0 0 0 49 0 1 2 3 4 5 5
我猜,这有一些我缺失的逻辑,因为它们看起来不像垃圾值,因为结果总是相同的。 做push_back之后,迭代器是重置还是什么? 我已经把它读到某个地方,在迭代它时附加一个向量并不是一个好主意。我的问题是为什么?
经过互联网搜索后,
if (*i == 1) {
size_t diff = i-v.begin();
v.push_back(5);
i = v.begin()+diff;
}
这将解决问题。
答案 0 :(得分:3)
您正在修改std::vector
,同时循环播放它。致电std::vector::push_back()
时,如果其当前size()
等于其当前capacity()
,则std::vector
必须重新分配其内部数据存储以增加其容量,然后才能存储新的价值。该重新分配将使循环iterator
无效(end()
迭代器始终无效,但您在每次迭代时都重新评估它,因此在这种情况下就可以了。)
要做你正在尝试的事情,要么:
reserve()
vector
在进入循环之前的容量,以避免重新分配,从而避免使循环iterator
失效。
在每次重新分配后重置迭代器。
改为使用std::list
,因为iterator
不会使循环std::list::push_back()
失效。
答案 1 :(得分:3)
因为std::vector::push_back
可能使所有迭代器无效。
如果new size()大于capacity(),那么所有迭代器和引用(包括过去的迭代器)都将失效。
对于您的代码,您可以使用std::vector::reserve
来避免重新分配。
将容器的容量增加到大于或等于new_cap的值。
int main() {
vector<int> v;
v.reserve(5); // ensure no reallocation until size() == 5
v.push_back(1);
v.push_back(2);
v.push_back(3);
v.push_back(4);
for (vector<int>::iterator i = v.begin();
i != v.end(); i++) {
cout << *i << endl;
if (*i == 1) {
v.push_back(5);
}
}
}
正如你所说,在迭代它时附加一个向量并不是一个好主意。
答案 2 :(得分:1)
现有答案中有一些不错的选择,但是当你知道由于push_back超出容量调整而面临潜在的迭代器失效时,值得一提的是另一个被遗忘的选项:
for (size_t i = 0; i < v.size(); ++i) {
cout << v[i] << endl;
if (v[i] == 1)
v.push_back(5);
}
这是“C风格”,但简单直观。