原文链接:https://blog.csdn.net/skyroben/article/details/70877008
1.迭代器
迭代器是一种面向对象的广义指针,用于指向容器中或流中的对象。可以看做是一种指向数据的指针。2.迭代器失效
向容器中添加或者删除元素的操作可能会使指向容器元素的迭代器失效,失效的迭代器将不指向任何元素。 一般有两种情况无法通过迭代器++操作遍历整个stl容器; 无法通过迭代器存取迭代器所指向的内存。3.vector一些操作使迭代器失效
3.1使用erase不恰当是迭代器失效:
删除容器中的偶数
测试用例:
#include <iostream>
#include <vector>
using namespace std;
void Printvector(vector<int> &l)
{
vector<int>::iterator it = l.begin();
while (it != l.end())
{
if (*it % 2 == 0)
{
//l.erase(it); //(1) 1 输出之后崩溃
//it=l.erase(it); //(2) 1 3 5 输出之后崩溃
}
cout << *it << " ";
++it;
}
cout << endl;
}
void Testvector()
{
vector<int> l;
l.push_back(1);
l.push_back(2);
l.push_back(3);
l.push_back(4);
l.push_back(5);
l.push_back(6);
Printvector(l);
}
int main()
{
Testvector();
return 0;
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
(1)程序输出1之后就崩溃的原因:
通过调试观察现象:
(2)程序输出1 3 5 之后就崩溃的原因:
通过调试观察现象:
STL中erase实现的源代码:
iterator erase(iterator position) {
if (position + 1 != end())
copy(position + 1, finish, position);
--finish;
destroy(finish);
return position;
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
如何解决上述问题:
void Printvector(vector<int> &l)
{
vector<int>::iterator it = l.begin();
while (it != l.end())
{
if (*it % 2 == 0)
{
it = l.erase(it);
}
else
{
cout << *it << " ";
++it;
}
}
cout << endl;
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
3.2使用push_bakc导致迭代器失效:
测试用例2:每次发现一个偶数就尾插一个0
void Printvector(vector<int> &l)
{
vector<int>::iterator it = l.begin();
while (it != l.end())
{
if (*it % 2 == 0)
{
l.push_back(0);
}
cout << *it << " ";
++it;
}
cout << endl;
}
void Testvector()
{
vector<int> l;
l.push_back(1);
l.push_back(2);
l.push_back(3);
l.push_back(4);
l.push_back(5);
Printvector(l);
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
3.3使用end返回的迭代器
使用了end返回的迭代器,而导致迭代器没有更新,使得程序崩溃。4.容器list的一些操作使迭代器失效
4.1删除元素eraser导致指向被删除元素的迭代器、指针引用失效
测试用例,删除当前迭代器,并不会对指向容器其他位置的迭代器造成影响#include <iostream>
#include <list>
using namespace std;
void Printlist(list<int> &l)
{
list<int>::iterator it = l.begin();
list<int>::iterator it1 = l.begin();
list<int>::iterator it2 = l.begin();
it1++;
while (it != l.end())
{
if (*it % 3 == 0)
{
l.erase(it1);
}
cout << *it << " ";
++it;
}
}
void Testlist()
{
list<int> l;
l.push_back(1);
l.push_back(2);
l.push_back(3);
l.push_back(5);
l.push_back(7);
Printlist(l);
}
int main()
{
Testlist();
return 0;
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34