vector的迭代器存在一定隐患,以下几种方式会导致其迭代器失效
resize、reserve、insert、assign、push_back。
1.push_back导致迭代器失效
示例代码:
#include<vector>
#include <iostream>
using std::cout;
using std::endl;
using std::vector;
int main()
{
vector<int> nums;
for (int i = 0; i < 13; i++)
{
nums.push_back(i);
}
vector<int>::iterator it = nums.begin();
it += 5;
cout << "容量是 " << nums.capacity() << endl;
cout << "it的值是 " << *it << endl;
nums.insert(it, 100);
cout << "insert后容量是 " << nums.capacity() << endl;
cout << "此时it指向的值是 " << *it << endl;
return 0;
}
运行结果:
分析原因:
vector在push_back的时候当容量不足时会触发扩容,导致整个vector重新申请内存,并且将原有的数据复制到新的内存中,并将原有内存释放,这自然是会导致迭代器失效的,因为迭代器所指的内存都已经被释放。
2.insert导致迭代器失效
示例代码:
#include<vector>
#include <iostream>
using std::cout;
using std::endl;
using std::vector;
int main()
{
vector<int> nums(5,2);
vector<int>::iterator it = nums.begin();
it += 5;
for (auto num : nums)
{
cout << num << " ";
}
cout << endl;
cout << "容量是 " << nums.capacity() << endl;
nums.insert(it, 10);
cout << "insert后容量是 " << nums.capacity() << endl;
for (auto num : nums)
{
cout << num << " ";
}
cout << endl;
return 0;
}
运行结果:
分析原因:
(1)插入操作导致vector扩容,迭代器失效原因和push_back相同
(2)插入操作引起vector内元素移动,导致被移动部分的迭代器失效
3.erase导致迭代器失效
示例代码:
#include<vector>
#include <iostream>
using std::cout;
using std::endl;
using std::vector;
int main()
{
int ar[] = { 1, 2, 3, 4, 0, 5, 6, 7, 8, 9 };
int n = sizeof(ar) / sizeof(int);
vector<int> v(ar, ar + n);
vector<int>::iterator it = v.begin();
while (it != v.end())
{
if (*it != 0)
std::cout << *it;//1234_
else
v.erase(it);//删除导致迭代器失效
it++;
}
return 0;
}
运行结果:
分析原因:
删除操作引起vector内元素移动,导致被移动部分的迭代器失效。
收获:
(1)这些能引起其底层空间改变的操作都会使迭代器失效,要小心使用。
1)vector的插入操作如果导致底层空间重新开辟,则迭代器就会失效。如果空间足够,不扩容时,迭代器不一定失效,比如push_back尾插,元素插入到空间末尾,在不扩容时不会对迭代器产生影响
2)vector删除,当前元素肯定失效,后面元素会牵扯到移动数据,因此删除元素后面的迭代器也会失效
(2)我们应当时刻遵守C++标准,避免使用无效迭代器;
(3)应当好好利用VC++在Debug模式下的迭代器检测功能,帮助我们提前发现可能出错的迭代器操作。