iterator not dereferencable问题

STL中的迭代器总是出现各种问题,这个是我在打表达式求值时碰到的...

综合网上的答案,一般来说有两种情况:

第一:访问了非法位置。

一般来说可能在queue为空时取front(),rear(),或者用list时误访最后一个结点,再或是在stack为空时进行了top(),pop()操作等。

一般来说用一下方法解决即可:

(1)在访问链表元素时判断当前迭代器是否指向链表尾

 1 list<Boom*>::iterator  ite=m_listBoom.begin();
 2     while(ite!=m_listBoom.end())
 3     {
 4         (*ite)->BoomShow(hdc);
 5         if(ite==m_listBoom.end())
 6         {
 7             return ;
 8         }
 9         ite++;
10     }

这是一段想对图片进行展示的代码,正常情况下红字部分我们是没有必要加的,但当你多次运行该程序时很可能会报错,错误为:list iterator not dereferencable

原因就是误访了尾节点。

(2)栈:

以下是表达式求值的部分代码(把中缀转后缀部分)

我在注释出刚开始是把!s1.empty()的判断放在后面的,于是就不停的报错...是不是很熟悉?

原因其实很简单,我们都知道在top(),pop()操作之前都要先判断栈是否为空

而又因为&&的短路原则,如果栈为空,则&&前面的表达式值为0,不会走后面对top()进行操作的代码,避免了错误

 1 #include<iostream>
 2 #include<string.h>
 3 #include<stack>
 4 using namespace std;
 5 stack<char>s1;
 6 stack<int>s2;
 7 char str[105];
 8 int num[11];
 9 int  prior(char c)
10 {
11     if(c==‘)‘||c==‘(‘) return 1;
12     else if(c==‘+‘||c==‘-‘) return 2;
13     else if(c==‘*‘||c==‘/‘) return 3;
14 }
15 void getLast(int n)
16 {
17     int i=0;
18     char tmp;
19     for(i=0;i<n;i++)
20     {
21         if(str[i]>=‘0‘&&str[i]<=‘9‘)
22         {
23             s2.push(str[i]);
24             if(str[i+1]>=‘0‘&&str[i+1]<=‘9‘)
25             {
26
27             }
28             else
29             {
30                 s2.push(‘#‘);
31             }
32         }
33         else
34         {
35                 if(s1.empty()||prior(str[i])>prior(s1.top())||str[i]==‘(‘/*||!s1.empty()*/)
36                 {
37                     s1.push(str[i]);
38                 }
39                 else if(!s1.empty()&&str[i]==‘)‘)
40                 {
41                     while(!s1.empty()&&(s1.top())!=‘(‘)
42                     {
43                         tmp=s1.top();
44                         s2.push(tmp);
45                         s1.pop();
46                     }
47                     s1.pop();
48                 }
49                 else
50               {
51                  while(!s1.empty()&&(prior(str[i])<=prior(s1.top())))//注意短路原则,要先判断是否为空为空自然不走后面的代码
52                 {                                                     //如果把判断是否为空放优先级判断之后,就会出现栈为空却
53                     tmp=s1.top();                                     //试图进行top(),pop()操作的情况
54                     s1.pop();                                        //会出现错误deque iterator not dereferencable
55                     s2.push(tmp);                                    //!所以要把s1.empty的判断放前面
56                 }
57                 s1.push(str[i]);
58
59             }
60         }
61     }
62     while(!s1.empty())
63     {
64         tmp=s1.top();
65         s1.pop();
66         s2.push(tmp);
67     }
68 }
69 int cal(int n)
70 {
71     return 0;
72 }
73 int main()
74 {
75     int n,i;
78     scanf("%s",&str);
79
80     n=strlen(str);
81     char tmp;
82     getLast(n);
83     while(!s2.empty())
84     {
85         tmp=s2.top();
86         s2.pop();
87         printf("%c",tmp);
88     }
89     return 0;
90 }

第二:多线程编程

在多线程编程里面,这种问题也出现的比较多。

两个线程同时访问同一个容器,也会导致出现这种情况。

解决办法:关键代码段。

不建议用互斥内核对象是因为关键代码段是用户层的,调用很快,互斥内核对象调用需要从用户态转入内核态!时间很长!

参考资料:http://blog.csdn.net/midle110/article/details/823858

时间: 2024-10-25 06:59:58

iterator not dereferencable问题的相关文章

BUG_vector iterator not dereferencable

1问题: bug提示图下图所示: 2. 分析 前前后后核实程序没有错误,退后根据bug提示信息 vector<Point>::iterator itPoint = tempSortedList.begin(); while (itPoint->y >= yLine && itPoint->y < yLine+MOVEUNION && itPoint != tempSortedList.end() ) 在vector的源文件中 提示内容的意

C++ STL之迭代器注意事项

1.两个迭代器组成的区间是前闭后开的 2.如果迭代器的有效性,如果迭代器所指向的元素已经被删除,那么迭代器会失效 http://blog.csdn.net/hsujouchen/article/details/8987233 3.迭代器指向的内容为空的时候(如已经指向end的时候)是不能访问值的,否则运行会崩溃(报错内容iterator not dereferencable) 1 string str_in; 2 cin>>str_in; 3 string ::iterator it; 4 i

转:STL迭代器失效问题

最近在项目开发中,遇到一个异常,经过测试,发现是迭代器失效问题,于是稍微总结了一下. vector迭代器失效测试: 测试程序: void vectorTest(){    vector<int> container;    for (int i = 0; i < 10; i++)    {        container.push_back(i);    } vector<int>::iterator iter;     for (iter = container.begi

Iterator接口。集合输出

在集合中支持以下几种方式. iterator ListIterator foreach输出 emumeration输出. 集合输出的标准操作: 集合输出的时候必须形成以下的思路:只要碰到了集合输出的操作,就一定使用iterator接口,这是最重要的标准. iterator接口的操作原理: iterator是专门的迭代输出接口,所谓的迭代输出就是将元素一个个进行判断,判断其是否有内容,如果有内容,则把内容输出. 对于iterator而言,其本身是一个借口,所以要想实例化,需要必须依靠collect

Java源码分析:深入探讨Iterator模式

作者:兄弟连 java.util包中包含了一系列重要的集合类.本文将从分析源码入手,深入研究一个集合类的内部结构,以及遍历集合的迭代模式的源码实现内幕. 下面我们先简单讨论一个根接口Collection,然后分析一个抽象类AbstractList和它的对应Iterator接口,并仔细研究迭代子模式的实现原理. 本文讨论的源代码版本是JDK 1.4.2,因为JDK 1.5在java.util中使用了很多泛型代码,为了简化问题,所以我们还是讨论1.4版本的代码. 集合类的根接口Collection

LeetCode OJ:Peeking Iterator(peeking 迭代器)

Given an Iterator class interface with methods: next() and hasNext(), design and implement a PeekingIterator that support the peek() operation -- it essentially peek() at the element that will be returned by the next call to next(). Here is an exampl

LeetCode——Peeking Iterator

Description: Given an Iterator class interface with methods: next() and hasNext(), design and implement a PeekingIterator that support the peek() operation -- it essentially peek() at the element that will be returned by the next call to next(). Here

Java Iterator和增强for循环 for each详解

Iterator是Java中的一个迭代器接口(Interface),用来提供标准的Java迭代器 Iterator支持泛型因为集合(Collection)类可以装入的类型是不确定的,从集合中取出的都是Object类型,加入泛型,就是告诉编译器确定要装入的对象类型,取值时就无需强制转换了. for each 是 Java 5 中新增的一个循环结构,本质上是一个Iterator,特点是可以用来遍历集合元素而不用考虑集合下标. 综合实例: package net.csdn.shf4715; impor

一大波Java来袭(六)——Java集合之Collection和Iterator接口

本文主要介绍Collection和Iterator接口. 一.Collection和Iterator接口 Collection接口是List.Set..Queue的父接口. Collection  c = new ArrayList(); 父类指向子类对象!优点:多态.动态链接.向上转型. 面向接口编程,被调用者对于调用者是完全透明的,可以随意替换子类,屏蔽了子类特有的东西. Demo:详细请参加:Java API文档 二.如何依次遍历集合中的元素? 普通情况下,当我们把一个对象"丢进"