迭代器失效的例子
来源:互联网 发布:为知笔记 知乎 编辑:程序博客网 时间:2024/04/27 19:38
vector迭代器的使用切不可真正当指针使,尽管底层会调用其偏特化版本,但是它自身调用是基于一个有用的前提:这个指针本身是有效的,即指向地址合法。
现在有个应用:
请编写一个方法,将字符串中的空格全部替换为“%20”。假定该字符串有足够的空间存放新增的字符,并且知道字符串的真实长度(小于等于1000),同时保证字符串由大小写的英文字母组成。
给定一个string iniString 为原始的串,以及串的长度 int len, 返回替换后的string。
测试样例:
“Mr John Smith”,13
返回:”Mr%20John%20Smith”
”Hello World”,12
返回:”Hello%20%20World”
于是我写了下面的代码:
class Replacement {public: string replaceSpace(string iniString, int length) { // /*****************错误发生在下面***********/ string::iterator front = iniString.end()-1; int c = count(iniString.begin(), iniString.end(), ' '); iniString.resize(length+c*2, ' '); /***************错误发生在上面*************/ string::iterator back = --(iniString.end()); while(iniString.begin() != front) { if (*front != ' ') { *back = *front; --back; --front; } else { *back = '0'; --back; *back = '2'; --back; *back = '%'; --back; --front; } } return iniString; }};
上面可以对迭代器直接+n,因为这个迭代器类型是RandomAcessIterator,所以合法。注意到注释部分,错误就发生在那一部分:段错误,为什么?迭代器失效了!!!
我们知道string的空间也是动态增长的,这个和vector类似,并不是在原有的空间末尾再续空间,而是开辟一个新的、原空间两倍大的内存区域,把原始数据拷贝过来后释放原来的空间。对这个有了了解,重点再看以下句子:
string::iterator front = iniString.end()-1; int c = count(iniString.begin(), iniString.end(), ' '); iniString.resize(length+c*2, ' ');
它的意思就是先找到原来string的最后一个字符,然后把这个string空间扩大,用来把空格替换为“20%”,很好理解。但是第一句话掉入一个陷阱:这个front在resize()之后,并不是我们想要的那最后一个字符的位置,它可能是任何东西,就是不是想要的,原因已经说过了。
那么如何避免这种错误?这只是一个习惯性的约束,因为在很多场合以上写法是合理的,比如list、map、set之类的容器,那么习惯上要保持一致才不容易犯错误,事实上,只需要将有可能造成容器变化的语句放置在迭代器定义之前就好,就像下面:
int c = count(iniString.begin(), iniString.end(), ' '); iniString.resize(length+c*2, ' '); string::iterator front = iniString.begin()+length-1;
保持一种习惯,每每碰到问题就会调节反射一般问自己:迭代器会失效吗?
- 迭代器失效的例子
- map删除元素时防止迭代器失效的例子
- 索引失效的几种例子
- 迭代器失效(2)—一个例子
- C++迭代器失效: 典型的迭代器失效.
- 迭代器失效的问题
- 迭代器的失效
- vector的迭代器失效
- 容器迭代器的失效
- 【C++】迭代器的失效
- 迭代器失效的场景
- 迭代器失效的总结
- STL迭代器失效的情况
- deque迭代器失效的困惑?
- STL迭代器失效的问题
- 关于迭代器失效的讨论
- 迭代器失效
- 迭代器失效
- and5.1PowerManagerService深入分析(三)updatePowerStateLocked函数
- 2015年最新苹果开发者账号注册流程详解
- ThinkPHP 解析访问路径的坑
- BZOJ 1197 [HNOI2006]花仙子的魔法 递推
- 我在项目阶段猛然醒来
- 迭代器失效的例子
- Android OkHttp完全解析 是时候来了解OkHttp了
- ubuntu源码安装ctags
- 如何使用友盟崩溃分析
- 处理语法高亮的一些问题
- SDN控制平面发展历史及趋势
- 关于使用matplotlib-legend方法失效问题
- NSUserDefault
- Android ListView异步加载图片乱序问题,原因分析及解决方案