vector迭代器失效的几种情况
在泛型编程还是STL的实际运用中,迭代器(iterator)无疑扮演者重要的角色。迭代器是一种类似于指针的对象(如可以内容提领,成员访问等),但他又不仅仅是一种普通的指针。关于迭代器失效,我们可以看下面这个例子:
#include<vector>
#include<list>
void PrintVector(const vector<int>& v)
{
vector<int>::const_iterator it = v.begin();
while (it!=v.end())
{
cout << *it << " ";
it++;
}
cout << endl;
}
void TestIterator()
{
//迭代器失效
vector<int> v;
v.push_back(1);
v.push_back(2);
v.push_back(2);
v.push_back(4);
v.push_back(2);
v.push_back(3);
v.push_back(4);
v.push_back(5);
v.push_back(4);
v.push_back(4);
v.push_back(6);
vector<int>::iterator it = v.begin();
while (it != v.end())
{
if (*it % 2 == 0)
{
it = v.erase(it);
++it;
}
}
PrintVector(v);
}
void main()
{
TestIterator();
}
这样的代码乍一看好像没有什么问题,但是他是有问题的,因为在vector是顺序存储的,在vector中删除一个元素之后,我们需要为vector重新分配一个空间,存放在旧的空间的元素被复制到新的空间,如果删除的这个元素的迭代器会指向下一个元素之后还++it,则在复制的时候找不到下一个元素,因此会使删除点及删除点之后的迭代器失效。正确做法是:
vector<int>::iterator it = v.begin();
while (it != v.end())
{
if (*it % 2 == 0)
{
it = v.erase(it);
}
else
{
++it;
}
}
PrintVector(v);
对于添加元素也是同理,如果当前容器中有10个元素,现在又要添加元素到容器中,如果内存中没有多余的空间,因此vector需要重新开辟空间来存储原来的元素以及新添加的元素。在新的空间复制原理来的元素,并插入新的元素,最后撤销原来的空间,这种情况发生会使所有迭代器都失效。
总结:vector迭代器的几种失效的情况:
1.当插入(push_back)一个元素后,end操作返回的迭代器肯定失效。
2.当插入(push_back)一个元素后,capacity返回值与没有插入元素之前相比有改变,则需要重新加载整个容器,此时first和end操 作返回的迭代器都会失效。
3.当进行删除操作(erase,pop_back)后,指向删除点的迭代器全部失效;指向删除点后面的元素的迭代器也将全部失效。
vector迭代器失效的几种情况的更多相关文章
- C++迭代器失效的几种情况总结
一.序列式容器(数组式容器) 对于序列式容器(如vector,deque),序列式容器就是数组式容器,删除当前的iterator会使后面所有元素的iterator都失效.这是因为vetor,deque ...
- vector迭代器失效的一种情形
使用过STL的人都应该知道关于迭代器失效的原理,这里以后vector迭代器失效为例: 第一种:当插入一个元素到vector中,如果插入后容器已满,那么容器将新开辟一块内存区域,然后 将原内存中的数据拷 ...
- MySQL索引失效的几种情况
1.索引不存储null值 更准确的说,单列索引不存储null值,复合索引不存储全为null的值.索引不能存储Null,所以对这列采用is null条件时,因为索引上根本 没Null值,不能利用到索引, ...
- mysql索引总结(4)-MySQL索引失效的几种情况
mysql索引总结(1)-mysql 索引类型以及创建 mysql索引总结(2)-MySQL聚簇索引和非聚簇索引 mysql索引总结(3)-MySQL聚簇索引和非聚簇索引 mysql索引总结(4)-M ...
- Spring事务失效的2种情况
使用默认的事务处理方式 因为在java的设计中,它认为不继承RuntimeException的异常是”checkException”或普通异常,如IOException,这些异常在java语法中是要求 ...
- C++vector迭代器失效的问题
转载:http://blog.csdn.net/olanmomo/article/details/38420907 转载:http://blog.csdn.net/stpeace/article/de ...
- Mybatis 缓存失效的几种情况
1 不在同一个sqlSession对象中 下面比较下载同一个sqlSession和不在同一sqlSession下面的两种情况: 同一sqlSession: @Test public final voi ...
- Mysql索引会失效的几种情况分析(转)
出处:http://www.jb51.net/article/50649.htm 索引并不是时时都会生效的,比如以下几种情况,将导致索引失效: 1.如果条件中有or,即使其中有条件带索引也不会使用(这 ...
- oracle数据库中索引失效的几种情况
原文1:https://blog.csdn.net/u012255097/article/details/102792683 原文2:https://www.cnblogs.com/lanseyita ...
随机推荐
- 如何降低Unity程序的Drawcall
[如何降低Unity程序的Drawcall] Unity can combine a number of objects at runtime and draws them together with ...
- 高性能Web服务器Nginx的配置与部署研究(10)核心模块之HTTP模块Location相关指令
一.基本语法 语法:location [= | ~ | ~* | ^~] </uri/> {...} 缺省:N/A 作用域:server 二.匹配规则 1. 四种匹配方式 = 精确匹配 ~ ...
- windows运行打开服务命令的方法 :
windows运行打开服务命令的方法 : 在开始->运行,输入以下命令 1. gpedit.msc-----组策略 2. sndrec32-------录音机 3. Nslookup------ ...
- Spring boot 开发组件
一.Jboot 描述:Jboot是一个基于jfinal 和 undertow开发的微服务框架.提供了AOP.RPC.分布式缓存.限流.降级.熔断.统一配置中心.swagger api自动生成.Open ...
- Ajax定时局部刷新
1.局部刷新一个地方 function refreshOnTime(){ $.ajax({ //配置 }); //7秒后重复执行该函数 setInterval('refreshOnTime', 700 ...
- python 类变量 在多线程下的共享与释放问题-乾颐堂
最近被多线程给坑了下,没意识到类变量在多线程下是共享的,还有一个就是没意识到 内存释放问题,导致越累越大 1.python 类变量 在多线程情况 下的 是共享的 2.python 类变量 在多线程情况 ...
- tp5 $this/Db
- not in查询不出数据问题
select ID from SmartCustomer where ID not in (select distinct CustomerID from SmartPromoter where Cu ...
- C++11新特性之auto
auto的使用 c++11引入了auto类型说明符,auto让编译器通过初始值来推算变量的类型,所以auto定义的变量必须有初始值. 使用auto也能在一条语句中声明多个变量,因为一条声明语句只能 ...
- linux 创建数据库
mysql -uroot -pxxxxxx 1. 修改服务器的字符集 打开/etc/mysql/my.cnf,在[mysqld]后添加character-set-server=utf8 2. 查看my ...