初夏小谈:vector中迭代器失效问题
在模拟vector中会发生一种错误,程序崩溃。经过调试发现当使用迭代器时当指向的空间发生扩容后,在对用迭代器指向的空间进行解引用时会发生程序崩溃。在vector中,我们知道迭代器可以看作是原生态的指针,那么对指针进行解应用发生崩溃,就说明了对一块不属于当前指针的空间进行了解引用。
在vector中使用迭代器发生崩溃会存在两种情况:
一、根据上面所说的情况就可以总结为:当容量发生改变时就有可能发生迭代器失效。例如(进行插入元素,增加有效元素个数,扩容时等等)可能引起另辟空间进行搬移数据就会产生迭代器失效的问题。
例子:
void TestVector5() { vector<int> v{ 1,2,3,4,5 }; for (auto& e : v) { cout << e << " "; } vector<int>::iterator it = v.begin(); v.reserve(16); cout << *it << endl; }
运行结果:
产生崩溃的原因就是:原来的空间进行扩容后,就在另一块内存上开辟了一片相应要求的空间并且将原来内存上的数据搬过去。但是it依旧是还是指向原来的空间上,原来的空间已经被释放。如果再次对it进行操作,就会崩溃,你想对释放的空间进行解引用吗?那是不可能的呵呵。
针对上述问题解决办法:
就是因为迭代器的指向不能自动跟着变化所以就进行手动跟上对应空间。
void TestVector5() { vector<int> v{ 1,2,3,4,5 }; for (auto& e : v) { cout << e << " "; } cout << endl; vector<int>::iterator it = v.begin(); v.reserve(16); it = v.begin(); cout << "*it = " << *it << endl; }
运行结果:
二、第二种情况就是在对迭代器所指向的元素删除时(erase),就会崩溃
代码例子:
void TestVector6() { vector<int> v{ 1,2,3,4,5 }; for (auto& e : v) { cout << e << " "; } cout << endl; vector<int>::iterator it = v.begin(); while (it != v.end()) { v.erase(it); } }
结果显示:
这是因为:当删除第一个数据后,所有数据都往前移动一次。但是it虽然指向第二个元素。但是它依然去找寻已经删除第一个数据,显然不会找到,迭代器也太执着了。就发生崩溃。
解决办法:就是每删除一个数据,就重新将迭代器指向第一个位置。脱离已故的主人吧,该换新主人了。呵呵。
void TestVector6() { vector<int> v{ 1,2,3,4,5 }; for (auto& e : v) { cout << e << " "; } cout << endl; vector<int>::iterator it = v.begin(); while (it != v.end()) { //v.erase(it); it = v.erase(it); for (auto& e : v) { cout << e << " "; } cout << endl; } }
运行结果:
总结一下迭代器失效问题:本质指针,指针所指向的空间失效了,从而指针指向了一块非法的空间。
珍&源码
上一篇: 初夏小谈:动态规划解决---01背包问题
下一篇: 初夏小谈:C++继承(二)之菱形虚拟继承