官方网站 建设情况汇报,长沙做网站公司 上联网络,专门做离异相亲的网站,wordpress直播主题vector 迭代器失效
迭代器的主要作用就是让算法能够不用关心底层数据结构#xff0c;其底层实际就是一个指针#xff0c;或者是对指针进行了封装#xff0c;比如#xff1a;vector的迭代器就是原生态指针T* 。因此迭代器失效#xff0c;实际就是迭代器底层对应指针所指向…vector 迭代器失效
迭代器的主要作用就是让算法能够不用关心底层数据结构其底层实际就是一个指针或者是对指针进行了封装比如vector的迭代器就是原生态指针T* 。因此迭代器失效实际就是迭代器底层对应指针所指向的空间被销毁了而使用一块已经被释放的空间 造成的后果是程序崩溃(即如果继续使用已经失效的迭代器程序可能会崩溃)。
对于vector可能会导致其迭代器失效的操作有
指定位置元素的删除操作–erase
VS下的
#include iostream
using namespace std;
#include vector
int main()
{int a[] { 1, 2, 3, 4 };vectorint v(a, a sizeof(a) / sizeof(int));int sz v.capacity();// 使用find查找3所在位置的iteratorvectorint::iterator pos find(v.begin(), v.end(), 3);// 删除pos位置的数据导致pos迭代器失效。v.erase(pos);cout *pos endl; // 此处会导致非法访问return 0;
}erase删除pos位置元素后pos位置之后的元素会往前搬移没有导致底层空间的改变理论上讲迭代器不应该会失效但是如果pos刚好是最后一个元素删完之后pos刚好是end的位置而end位置是没有元素的那么pos就失效了。因此删除vector中任意位置上元素时vs就认为该位置迭代器失效了。
与vector类似string在插入扩容操作erase之后迭代器也会失效
#include iostream
#include string
using namespace std;
int main()
{string s(hello);auto it s.begin();// 放开之后代码会崩溃因为resize到20会string会进行扩容// 扩容之后it指向之前旧空间已经被释放了该迭代器就失效了// 后序打印时再访问it指向的空间程序就会崩溃//s.resize(20, !);while (it ! s.end()){cout *it;it;}cout endl;it s.begin();while (it ! s.end()){it s.erase(it);// 按照下面方式写两编译器运行时程序都会崩溃因为erase(it)之后// it位置的迭代器就失效了// s.erase(it); //it;}return 0;
}Linux下g编译器对迭代器失效的检测并不是非常严格处理也没有vs下极端。
// 2. erase删除任意位置代码后linux下迭代器并没有失效
// 因为空间还是原来的空间后序元素往前搬移了it的位置还是有效的
#include iostream
#include vector
#include algorithm
using namespace std;
int main()
{vectorint v{1,2,3,4,5};vectorint::iterator it find(v.begin(), v.end(), 3);v.erase(it);cout *it endl;while(it ! v.end()){cout *it ;it;}cout endl;return 0;
} //erase删除的迭代器如果是最后一个元素删除之后it已经超过end
// 此时迭代器是无效的it导致程序崩溃
#include iostream
#include vector
#include algorithm
using namespace std;
int main()
{vectorint v{1,2,3,4,5};// vectorint v{1,2,3,4,5,6};auto it v.begin();while(it ! v.end()){if(*it % 2 0)v.erase(it);it;}for(auto e : v){cout e ;}cout endl;return 0;
}使用第一组数据时程序可以运行 使用第二组数据时程序最终会崩溃 从上述二个例子中可以看到SGI STL中迭代器失效后代码并不一定会崩溃但是运行结果肯定不对如果it不在begin和end范围内肯定会崩溃的。 迭代器失效不要在访问了行为结果未定义(不同的编译器有不同的实现)