C++复习之迭代器失效的问题
2020-07-14 05:22
375 查看
迭代器的失效问题
第一种场景:
首先咱们先用库里面自带的vector容器,把容器中所有偶数删除
#include <iostream> #include <vector> using namespace std; int main() { vector<int> vec; for (int i = 0; i < 20; ++it) { vec.push_back(rand() % 100 + 1); } //把容器中所有偶数删除 auto it = vec.begin(); for (; it != vec.end(); ++it) { if (*it % 2 == 0) { //迭代器失效的问题第一次调用erase之后,迭代器it就失效了 vec.erase(it);//erase是vector底层提供的删除方法,把it指向的当前元素删除掉 } } return 0; }
当我们执行程序之后,会发现进程意外中止。这是因为第一次调用erase之后,迭代器it就失效了 ,之后的for循环内的 ++it 操作就是出错。
如果只删除一次,则进程正常结束。
for (; it != vec.end(); ++it) { if (*it % 2 == 0) { vec.erase(it); break; } }
原因是当你删除一个元素后,从这个元素的位置到容器结尾之间的迭代器全部失效。再进行++、–、!=等操作时,都会出现错误。
第二种场景
给容器内所有的偶数前面添加一个小于偶数值1的数字
#include <iostream> #include <vector> using namespace std; int main() { vector<int> vec; for (int i = 0; i < 20; i++) { vec.push_back(rand() % 100 + 1); } //给容器内所有的偶数前面添加一个小于偶数值1的数字 auto it = vec.begin(); for (; it != vec.end(); ++it) { if (*it % 2 == 0) { //这里的迭代器在一次insert后,iterator就失效了 vec.insert(it,*it - 1); } } return 0; }
当我们执行程序之后,会发现进程意外中止。这是因为第一次调用erase之后,迭代器it就失效了 ,之后的for循环内的 ++it 操作就是出错。
如果只插入一次,则进程正常结束。
即加入break。
auto it = vec.begin(); for (; it != vec.end(); ++it) { if (*it % 2 == 0) { vec.insert(it,*it - 1); break; } }
增加也是一样,原因是当你插入一个元素后,如果容器不出现扩容的情况,从这个元素的插入位置到容器结尾之间的迭代器全部失效。再进行++、–、!=等操作时,都会出现错误。如果容器出现扩容的情况,系统会开辟一个新的内存,在原来内存上保存的所有迭代器都会失效。
迭代器为什么会失效?
1.当容器调用erase方法后,当前位置到容器末尾元素的所有迭代器全部都失效了。
2.当容器调用insert方法后, 当前位置到容器末尾元素的所有迭代器全部都失效了。insert如果引起容器内存扩容,原来容器的所有的迭代器完全失效。
迭代器失效后的解决方法
对插入/删除点的迭代器进行更新操作
以删除为例:当你将当前位置的元素删除后,指向当前位置的迭代器就失效了,会在当前位置产生一个新的迭代器iterator并返回。所以我们通过更新迭代器的方法来解决这个问题。
#include <iostream> #include <vector> using namespace std; int main() { vector<int> vec; for (int i = 0; i < 20; i++) { vec.push_back(rand() % 100 + 1); } //第一次打印 for (int v : vec) { cout << v << " "; } cout << endl; //第一种场景删除 //把容器中所有偶数删除 auto it = vec.begin(); while(it != vec.end()) { if (*it % 2 == 0) { //迭代器失效的问题第一次调用erase之后,迭代器it就失效了 it = vec.erase(it);//更新当前的迭代器 } else { ++it; } } #endif //再次打印 for (int v : vec) { cout << v << " "; } cout << endl; return 0; }
以插入为例:
#include <iostream> #include <vector> using namespace std; int main() { vector<int> vec; for (int i = 0; i < 20; i++) { vec.push_back(rand() % 100 + 1); } //第一次打印 for (int v : vec) { cout << v << " "; } cout << endl; //第二中场景插入 //给容器内所有的偶数前面添加一个小于偶数值1的数字 auto it = vec.begin(); for (; it != vec.end(); ++it) { if (*it % 2 == 0) { it = vec.insert(it,*it - 1); ++it;//当如果当前是偶数执行插入操作后,会把原来位置上的元素挤到下一个位置,所以迭代器需要++两次 } } //再次打印 for (int v : vec) { cout << v << " "; } cout << endl; return 0; }
相关文章推荐
- c++关于顺序容器指针迭代器失效问题
- 如何处理C++删除容器中元素时导致的迭代器失效问题
- C++中容器迭代器删除失效问题
- C++ STL 迭代器失效问题的剖析
- C++ STL 迭代器失效问题
- C++关于迭代器删除(erase)插入(insert)失效问题
- C++关于迭代器删除(erase)插入(insert)失效问题http://m.blog.csdn.net/blog/a327369238/26715187
- C++中迭代器失效的问题
- C++ STL中迭代器失效的问题
- C++中迭代器失效的问题
- c++关于顺序容器指针迭代器失效问题
- c++ Vector《二》 主要包括:《Vector的增删查找接口实现》《迭代器失效的问题》《常见的迭代器失效的场景》
- C++ STL 迭代器失效问题
- c++中STL的迭代器失效问题
- (leetcode169)C++解决多数元素问题以及迭代器和map的使用
- 泛式算法,仿函数和迭代器失效问题
- map和vector的迭代器失效问题
- 迭代器失效问题
- C++中防止STL中迭代器失效__map/set等关联容器vector/list/deque等序列容器_如何防止迭代器失效_即erase()的使用
- 有关于STL中的迭代器失效问题[转自CSDN BLOG]