中山网站排名推广,没有icp备案的网站,网站建设公司郑州,深圳平面设计培训目录 什么是迭代器失效导致迭代器失效的操作VS和g环境下对与迭代器失效的态度 什么是迭代器失效
迭代器的底层其实就是一个指针#xff0c;或者对指针进行了封装
vector的迭代器就是一个指针T* 一个迭代器指向某一个空间#xff0c;此时这块空间被释放了#xff0c;这个迭… 目录 什么是迭代器失效导致迭代器失效的操作VS和g环境下对与迭代器失效的态度 什么是迭代器失效
迭代器的底层其实就是一个指针或者对指针进行了封装
vector的迭代器就是一个指针T* 一个迭代器指向某一个空间此时这块空间被释放了这个迭代器仍指向原来的那个空间这个就叫迭代器的失效
如果继续使用已经失效的迭代器程序可能会崩溃 导致迭代器失效的操作
引起底层空间发生变化的操作都很有可能引起迭代器失效
迭代器失效主要都是由insert和erase导致的 下面我们看一个insert导致迭代器失效的情况
我们首先定义一个vectorint对象和一个迭代器
void test6()
{vectorint v{ 1,2,3,4,5,6 };auto it v.begin();
}此时v的size()的值和capacity()的值都为6如果再向v中插入数据就需要扩容。
void test6()
{vectorint v{ 1,2,3,4,5,6 };auto it v.begin();v.insert(it, 0);//此处会扩容
}v.insert(it, 0)会导致扩容扩容其实就是另开辟一块更大空间原空间销毁所以此时迭代器it已经失效了因为后面没有再使用it所以暂时不会报错。 此处如果再使用已经失效的迭代器it就会报错
void test6()
{vectorint v{ 1,2,3,4,5,6 };auto it v.begin();v.insert(it, 0);//此处会扩容v.insert(it, 0);
}所以想要迭代器不失效就要为迭代器重新赋值
insert函数在库中的定义为
iterator insert (iterator position, const value_type val)可以看到它的返回值是iterator类型的这其实返回了一个处理后不失效的迭代器是指向第一个新插入元素的迭代器。
void test6()
{vectorint v{ 1,2,3,4,5,6 };auto it v.begin();it v.insert(it, 0);//此处会扩容v.insert(it, 10);//不会报错
}下面看一下erase导致失效的情况
其实大多数情况下使用erase并不会导致迭代器
void test7()
{vectorint v{ 1,2,3,4,5,6 };auto it v.begin()3;v.erase(it);
}这里迭代器it指向的是4v.erase(it)删除4后后面的元素会向前补上来没有导致底层空间的改变理论上讲迭代器不应该会失效
如果pos刚好是最后一个元素删完之后pos刚好是end的位置而end位置是没有元素的那么pos就失效了
以及如果vector中如果只有一个元素迭代器恰好指向这个元素那么erase后迭代就会失效
可以看出erase虽然有的情况会导致迭代器失效有点情况不会导致迭代器失效但是在VS环境下就认为删除vector中任意位置上元素时vs就认为该位置迭代器失效了。 其实与vector类似string在插入扩容操作erase之后迭代器也会失效 VS和g环境下对与迭代器失效的态度
VS环境下对于迭代器失效十分严格只要有迭代器失效的情况编译器就会报错只要删除vector中任意位置上元素时就认为该位置迭代器失效了报错但是linux上的g编译器对迭代器失效的检测并不是非常严格处理也没有vs下极端。 扩容之后迭代器已经失效了程序虽然可以运行但是运行结果已经不对了erase删除任意位置代码后linux下如果迭代器没有失效程序还是会运行erase删除的迭代器如果是最后一个元素删除之后it已经超过end如果it还是会报错的所以迭代器失效后代码并不一定会崩溃但是运行结果肯定不对如果it不在begin和end范围内肯定会崩溃的