实例一
vector<int> v1;
v1.push_back(1);
v1.push_back(2);
v1.push_back(3);
v1.push_back(4);
v1.push_back(5);
vector<int>::iterator it = find(v1.begin(), v1.end(), 2);
if (it != v1.end())
{
//如果insert中发生扩容,那么会导致it指向空间被释放
//it本质就是一个野指针,这种问题,我们就叫迭代器失效
v1.insert(it, 20);
}
*it=10;//此时it访问的还是之前的空间
如果在insert后,刚好进行了扩容,那么就会开辟一个新的空间,那么it指向的还是之前的空间,那么我们再次使用it访问所指向的内容时就会失效。由此可得,发生迭代器失效的很重要一点就是it并没有及时更新,还停留在老空间里面,而且大概率都是扩容引起的,不难能猜到只要牵扯到可能使空间进行扩容的,扩容后再次使用迭代器访问数据的,都可能会出现迭代器失效这种情况。
实例二
int main()
{
vector<int> v1;
v1.push_back(1);
v1.push_back(2);
v1.push_back(3);
v1.push_back(4);
vector<int>::iterator it = v1.begin();
while (it != v1.end())
{
if (*it % 2 == 0)
{
v1.erase(it);
}
it++;
}
for (auto e : v1)
{
cout << e << " ";
}
cout << endl;
return 0;
}
我们初心是为了删除v1中的偶数,可是当我们erase之后,erase那个数后面的数会整体向前移动,然后it还要++,这就造成了it并不是指向了删除那个数据的下一个位置,就造成了迭代器失效。
由图可知,v.end()与it已经错开了,it已经失效。
解决方法
我们只要及时更新it指向的位置,就可以解决相关问题,避免迭代器失效。
实例一
vector<int> v1;
v1.push_back(1);
v1.push_back(2);
v1.push_back(3);
v1.push_back(4);
v1.push_back(5);
vector<int>::iterator it = find(v1.begin(), v1.end(), 2);
if (it != v1.end())
{
it=v1.insert(it, 20);//及时更新了it指向的位置
}
实例二
int main()
{
vector<int> v1;
v1.push_back(1);
v1.push_back(2);
v1.push_back(3);
v1.push_back(4);
vector<int>::iterator it = v1.begin();
while (it != v1.end())
{
if (*it % 2 == 0)
{
it=v1.erase(it);
}
it++;
}
for (auto e : v1)
{
cout << e << " ";
}
cout << endl;
return 0;
}