关于vecteor::erase(iterator++),导致崩溃的问题
2013-06-29 19:00
513 查看
由于使用Cygwin不支持 iter = vector::erase(iterator++)这种写法,导致在使用erase的时候,我都将其改成erase(iterator++)写法。不过最近却因为该写法,导致了崩溃的问题。
网络上资料说:
一种是如数组类的容器 deque,vector,string.
这种情况下只要erase(iterator) 就好了。
另一种是map,set这样的结点型的容器。
则需要使用你这种erase(iterator++),才会跳到下一个。
也就是说数组一类的容器,调用erase后,会对后面的元素进行移动,并有可能将所有与移动的元素相关的iterator都设置为失效。导致iterator++后,依然失效。
网络的资料:
当iterator 的类型是std::vector<int>::iterator的时候,erase(iterator++)这样的写法是错误的。例如:
在设置断点的一行,在vs2010中按F11单步调试,你会发现:
iter++操作将iter加1后将还没有加一的值赋给临时变量_tmp,_tmp迭代器此时指向vector的开头,即元素0,iter此时指向_tmp的下一个元素即元素1。_tmp在iter++操作后返回给erase()。
erase()将_tmp所指向的元素(即0)删除。
注意该处erase还执行了其他的操作 这也是为什么以数组存储方式的容器(例如vector)和以类似链表存储方式的容器(例如list)的区别。erase() 删除了vector容器开头元素之后,类似于数组的做法,还函数还将删除元素之后所有的元素往前挪了一个位置。此时vector 元素的排列顺序是1 2 3 4 5 6 7 8 9 9。
接下来再将最后一个元素9删除,释放其存储空间。
这个时候iter指向的位置还是容器开始位置的下一个位置,也就是2! 而不是我们想要的1。调试的过程中可发现这一点。但是该程序运行时发生了assertion failure。原因是编译器起到了很好的保护机制:猜测当erase()函数返回之前,所有与指向容器iv的迭代器都打上的失效的标记,接下来再使用这些迭代器就会发生断言错误。
网络上资料说:
一种是如数组类的容器 deque,vector,string.
这种情况下只要erase(iterator) 就好了。
另一种是map,set这样的结点型的容器。
则需要使用你这种erase(iterator++),才会跳到下一个。
也就是说数组一类的容器,调用erase后,会对后面的元素进行移动,并有可能将所有与移动的元素相关的iterator都设置为失效。导致iterator++后,依然失效。
网络的资料:
当iterator 的类型是std::vector<int>::iterator的时候,erase(iterator++)这样的写法是错误的。例如:
int main( ) { std::vector<int> vi; for(int i = 0; i < 10; i++) { vi.push_back(i); } for (std::vector<int>::iterator i = vi.begin(); i != vi.end(); i++) { std::cout << *i << " "; }// output 0 1 2 3 4 5 6 7 8 9 std::cout << '\n'; std::vector<int>::iterator iter = vi.begin(); vi.erase(iter++); // 该行设置断点 cout <<*iter << endl; // 发生断言错误 }
在设置断点的一行,在vs2010中按F11单步调试,你会发现:
iter++操作将iter加1后将还没有加一的值赋给临时变量_tmp,_tmp迭代器此时指向vector的开头,即元素0,iter此时指向_tmp的下一个元素即元素1。_tmp在iter++操作后返回给erase()。
erase()将_tmp所指向的元素(即0)删除。
注意该处erase还执行了其他的操作 这也是为什么以数组存储方式的容器(例如vector)和以类似链表存储方式的容器(例如list)的区别。erase() 删除了vector容器开头元素之后,类似于数组的做法,还函数还将删除元素之后所有的元素往前挪了一个位置。此时vector 元素的排列顺序是1 2 3 4 5 6 7 8 9 9。
接下来再将最后一个元素9删除,释放其存储空间。
这个时候iter指向的位置还是容器开始位置的下一个位置,也就是2! 而不是我们想要的1。调试的过程中可发现这一点。但是该程序运行时发生了assertion failure。原因是编译器起到了很好的保护机制:猜测当erase()函数返回之前,所有与指向容器iv的迭代器都打上的失效的标记,接下来再使用这些迭代器就会发生断言错误。
相关文章推荐
- 关于STL erase的iterator失效问题
- 关于STL的list,vector等用迭代器iterator,用erase删除元素出现的问题。
- 关于vector中使用erase删除元素后导致越界的问题
- 关于tomcat连接池爆满导致系统崩溃的问题
- 关于STL的list,vector等用迭代器iterator,用erase删除元素出现的问题。
- 关于STL erase的iterator失效问题
- 关于Android切换系统字体大小和字体样式导致App崩溃或者界面错乱的问题
- 关于SDWebImage加载高清图片导致app崩溃的问题
- 关于Usb直接拔出导致的进程崩溃问题
- 【Android开发经验】关于主题引用混乱导致程序运行崩溃的问题
- 关于主布局在横竖屏转换时导致程序崩溃问题
- 【Android开发经验】关于主题引用混乱导致程序运行崩溃的问题
- 一次关于更改UI导致autolayout系统崩溃的问题
- 全量导入数据 导致solr内存溢出 崩溃问题解决
- 关于Tomcat导致工程部分功能代码异常的问题
- 关于多线程中涉及UI操作,导致UI线程阻塞问题
- 关于win 8.1 平台打开ADT虚拟手机导致蓝屏重启问题解决
- 关于zynq系统消息输出串口导致电路板无法启动的问题
- 关于iOS10 获取权限导致Crash问题的解决办法
- 关于js的ajax方法导致跨域问题的解决办法