博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
vector iterators incompatible 删除map,list中元素时,应注意的问题
阅读量:6431 次
发布时间:2019-06-23

本文共 2011 字,大约阅读时间需要 6 分钟。

1.vector iterators incompatible

发现引发这个错误的代码如下:

for (VectorType::iterator it = someVector.begin();; it != someVector.end();++it;)
{
    if (*it== value)
    {
        someVector.erase(it);
    }
}
代码中,在erase操作后,没有修改it就继续循环,在与end()比较时,断言出现。
这里的主要问题是,vector可以用任意方法实现erase,不保证在erase一个元素后,后续的元素一定被移动到这个iterator所引用的位置(地址)。当然,这在几乎所有STL的实现中,都是对的,这也就是以前用VC6编译后运行没有问题的原因。但如果这里用的不是vector,而是list或是map,运行到这里,程序会毫不犹豫的崩溃。
正确的做法是这样的:
STL里所有的容器类的erase实现都会返回一个iterator,这个iterator指向了“当前删除元素的后继元素,或是end()”
因此,在遍历容器的所有元素过程中通过erase删除一个元素后,将erase的返回值赋给迭代变量:
for (VectorType::iterator it = someVector.begin();; it != someVector.end();)
{

    if (*it== value)

    {
        it = someVector.erase(it);
    }
    else
    {
        ++it;
    }
}

有些情况可能不需要如上做法:

1。不需要继续遍历

VectorType::iterator it=someVector.find(value)

{

   if (it!=someVector.end())

  someVector.erase(it);

}

2 删除后直接return

for (VectorType::iterator it = someVector.begin();; it != someVector.end();)

{

    if (*it== value)

    {
        it = someVector.erase(it);

    return;

    }

}

P.S. 可以看出,VS2005带的STL增加了更多的调试特性以避免出现STL的一些错误,有条件的话最好用VS2005的STL。如果没有VS2005,也可以使用STLport,STLport在调试特性上也非常出色。

如果你要略过这个检查,可以用#define _HAS_ITERATOR_DEBUGGING 0 不过建议还是检查线程的同步代码。

2.空Vector问题。不允许引用空vector的begin迭代器,因为vector是空的,自然不会有第一个项目,使用也会引发vector iterators incompatible。

 

3.vector同时读写引发。vc2005 对于迭代器的匹配是非常严格的,通常这种错误是因为两个不同的迭代器操作同一个 vector,或者是因为迭代器在遍历vector时,vector的链表改变了,就会引发这种错误,比如vector在遍历的途中,别的位置push_back()一个元素,这时迭代器就失效了,导致错误。可以使用临界区互斥访问。

 

4.迭代器越界,则相应会调用一个非法参数处理程序。

再次提醒,可以通过抛出一个越界异常来避免产生非法参数问题。在代码中加入#define value of _SECURE_SCL_THROWS,并把value值设为1,这样就不会调用非法参数处理程序,而是产生一个异常了。
也可以通过设置#defined value of _SECURE_SCL值为零,关闭此迭代器检查,通常默认情况下,此选项是打开的。

 

5.VS2005编译Release版STL的迭代器bug。经测试Unicode版的比较容易出这个问题,就是莫名其妙的迭代器错误。

微软的原文:The bug afflicted all Standard containers (vector, deque, list, set, multiset, map, multimap, and string) when _HAS_ITERATOR_DEBUGGING was disabled and _SECURE_SCL was enabled. Additionally, deque was afflicted when both were disabled.解决办法是

#ifndef _DEBUG

#define _SECURE_SCL 0

#endif

转载于:https://www.cnblogs.com/zhangjing0502/archive/2012/02/29/2372898.html

你可能感兴趣的文章
PHP cURL快速入门
查看>>
在errpt中报E87EF1BE的解决方法(转载)
查看>>
aix chfs及mklvcopy报错的解决方法
查看>>
取消新增的constraints
查看>>
MAC OS X 使用记录
查看>>
Azure 中使用 iPerf 进行网络带宽测试
查看>>
OPTIMIZE TABLE
查看>>
flask框架+pygal+sqlit3搭建图形化业务数据分析平台
查看>>
Fedora24下MySQL开发环境搭建
查看>>
shell实战训练营Day20
查看>>
jQuery 之 TAB切换菜单
查看>>
mysql 数据库集群搭建:(二)3台CentOS-7安装Percona-XtraDB-Cluster-57集群
查看>>
Jenkins实战演练之Windows系统节点管理
查看>>
MySQL高可用架构之MHA
查看>>
excel2013使用分列功能拆分数据
查看>>
如何玩转小程序+公众号?手把手教你JeeWx小程序CMS与公众号关联
查看>>
kibana平台增加安全认证
查看>>
1.8 nginx域名跳转
查看>>
PHP面向对象之接口编程
查看>>
使用 Docker Compose 管理多个容器实例
查看>>