这个可能适用于某些编译器/操作系统,并与其他人崩溃。与" List"相同的代码它工作正常,使用" vector"只有我面临未定义的行为输出。 STL(矢量)是安全的??
注意:这不是一个实时代码,我只是通过一些示例程序来实现它。
#include <vector>
#include <iostream>
using namespace std;
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 0 3 4 0 0 4113 0 858851888 943206709 2617 。 。 1 2 3 4 五 5
#include <list>
#include <iostream>
using namespace std;
int main() {
list<int> v;
v.push_back(1);
v.push_back(2);
v.push_back(3);
v.push_back(4);
for (list<int>::iterator i = v.begin();
i != v.end(); i++) {
cout << *i << endl;
if (*i == 1) {
v.push_back(5);
}
}
}
带列表的输出: 1 2 3 4 5
答案 0 :(得分:6)
循环中的一行:
v.push_back(5);
可能使迭代器i
无效(在需要重新分配的情况下),因此从那时起++i
是未定义的行为。
解决这个问题的一种可能性是首先保留向量,这样就不会发生重新分配:
vector<int> v;
v.reserve(5); // reserve enough to keep all the pushed items
v.push_back(1);
...
答案 1 :(得分:1)
您缺少的概念是&#34;迭代器失效&#34;。 std::vector
只是一个容量有限的动态数组。添加新元素会导致数组大小大于容量时,需要重新分配,这会使向量的所有迭代器无效。这是在标准草案中的#34; 23.3.7.5向量修饰符&#34;部分中定义的,其中涉及insert
和push_back
:
另一方面,备注:如果新大小大于旧容量,则会导致重新分配。如果没有重新分配, 插入点之前的所有迭代器和引用都保持有效。
std::list
是一个双向链表。因此,不需要对列表中已有的任何元素进行重新分配,只有std::list<T>::end()
迭代器无效。但是,由于您在循环条件中调用该方法,因此您的代码恰好可以正常工作。