随笔 - 96  文章 - 255  trackbacks - 0
<2010年6月>
303112345
6789101112
13141516171819
20212223242526
27282930123
45678910

E-mail:zbln426@163.com QQ:85132383 长期寻找对战略游戏感兴趣的合作伙伴。

常用链接

留言簿(21)

随笔分类

随笔档案

SDL相关网站

我的个人网页

我的小游戏

资源下载

搜索

  •  

积分与排名

  • 积分 - 488853
  • 排名 - 37

最新评论

阅读排行榜

评论排行榜

设计一段演示程序:打印n个数字,然后指定擦掉其中的某一个,重新打印剩下的数字。

#include <iostream>
#include 
<vector>

using std::cout;
using std::cin;
using std::endl;
using std::vector;

int main(int argc, char* argv[])
{
    
const int MAX = 10;
    vector
<int> v;
    
for (int i = 0; i < MAX; i++) {
        v.push_back(i);
        cout 
<< v[i] << '\t';
    }

    
int ers = -1;
    
while ( ers < 0 || ers >= MAX) {
        cout 
<< "Erase No.";
        cin 
>> ers;
    }

    
for (vector<int>::const_iterator i = v.begin(); i != v.end(); i++) {
        
if (*== ers) {
            v.erase(i);
        }
    }

    
for (vector<int>::const_iterator i = v.begin(); i != v.end(); i++) {
        cout 
<< *<< '\t';
    }
    cout 
<< endl;

    
return 0;
}
这个程序看似没什么错误,可以顺利编译,也可以顺利运行,甚至,大部分情况下可可以正常完成。
我们这里设置的n为10(MAX),事实上,我们擦掉0到8都没有问题,但是,我们要擦掉9的时候,程序却出错了!
在我们遍历查找对等值的循环中,一开始v.end()指向第10个元素(数值为9)的后面一个位置(不存在的第11个元素的位置)。当迭代器指向第10个元素(数值为9)的时候,v.erase()生效运行;下一轮循环中,迭代器本来应该指向第11个元素的位置,并且等于v.end()并结束循环。但是,因为我们擦掉了vector中的一个元素,v.end()指向的是现在的最后一个元素——第9个元素的后面,也就是第10个元素的位置。这样,迭代器到了11,而判断确是其是否到10,这将永远无法实现,形成了一个逻辑bug,所以系统抛出错误了。
一个修正的办法是把需要擦掉的迭代器找出来,在循环结束后再擦掉,下面修改后的程序就可以正常的擦掉9了。
#include <iostream>
#include 
<vector>

using std::cout;
using std::cin;
using std::endl;
using std::vector;

int main(int argc, char* argv[])
{
    
const int MAX = 10;
    vector
<int> v;
    
for (int i = 0; i < MAX; i++) {
        v.push_back(i);
        cout 
<< v[i] << '\t';
    }

    
int ers = -1;
    
while ( ers < 0 || ers >= MAX) {
        cout 
<< "Erase No.";
        cin 
>> ers;
    }

    vector
<int>::const_iterator ers_i;
    
for (vector<int>::const_iterator i = v.begin(); i != v.end(); i++) {
        
if (*== ers) {
            ers_i 
= i;
        }
    }
    v.erase(ers_i);

    
for (vector<int>::const_iterator i = v.begin(); i != v.end(); i++) {
        cout 
<< *<< '\t';
    }
    cout 
<< endl;

    
return 0;
}
posted on 2010-06-10 11:03 lf426 阅读(1654) 评论(1)  编辑 收藏 引用 所属分类: 语言基础、数据结构与算法

FeedBack:
# re: 迭代器(iterator)“擦”(erase)出的错误 2014-11-28 21:07 lizh
演示代码有点问题:
v.erase(i) i不能为const_iterator对象。  回复  更多评论
  

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理