如何解决vector容器erase崩溃

qq_16600121 2014-10-10 11:15:12
我有一个大的列表树,每个选项都有复选框,当我选中一个选项的时候就会将其信息push到一个容器里面,但当我在选中另一个选项时就会自动取消开始那个选项并且清除容器,问题就是在我erase它的时候程序崩溃在erase内部了,这块不是很懂,求高手帮我看一下。代码如下:
vec_Task::iterator Iter1 ;
Iter1=CGlobal::s_resMng._taskList.begin();
for(;Iter1!=CGlobal::s_resMng._taskList.end();Iter1++)
{
TaskNode* p= *Iter1;
if(p->Task == name) //name就是对应我要删的那个选项
{
CGlobal::s_resMng._taskList.erase(Iter1); //此处出现bug 20141009
break;
}
}

崩溃的具体地方是在vector.cpp里面:
#if _ITERATOR_DEBUG_LEVEL == 2
iterator erase(const_iterator _Where)
{ // erase element at where
if (_VICONT(_Where) != this
|| _VIPTR(_Where) < this->_Myfirst
|| this->_Mylast <= _VIPTR(_Where))
_DEBUG_ERROR("vector erase iterator outside range");
_Move(_VIPTR(_Where) + 1, this->_Mylast, _VIPTR(_Where));
_Destroy(this->_Mylast - 1, this->_Mylast);
_Orphan_range(_VIPTR(_Where), this->_Mylast);
--this->_Mylast;
return (_Make_iter(_Where));
}

_Orphan_range代码如下:
#if _VECTOR_ORPHAN_RANGE
void _Orphan_range(pointer _First, pointer _Last) const
{ // orphan iterators within specified (inclusive) range
_Lockit _Lock(_LOCK_DEBUG);
const_iterator **_Pnext = (const_iterator **)this->_Getpfirst();
if (_Pnext != 0)
while (*_Pnext != 0)
if ((*_Pnext)->_Ptr < _First || _Last < (*_Pnext)->_Ptr)
_Pnext = (const_iterator **)(*_Pnext)->_Getpnext();
else
{ // orphan the iterator
(*_Pnext)->_Clrcont();
*_Pnext = *(const_iterator **)(*_Pnext)->_Getpnext();
}
}


我单步执行后发现程序在while (*_Pnext != 0)处循环了大概6次后在if判断这块崩溃不能往下执行,提示发生访问内存冲突,当我关闭程序后,程序在utility.cpp跳出中断:
inline void _Container_base12::_Orphan_all()
{ // orphan all iterators
#if _ITERATOR_DEBUG_LEVEL == 2
if (_Myproxy != 0)
{ // proxy allocated, drain it
_Lockit _Lock(_LOCK_DEBUG);

for (_Iterator_base12 **_Pnext = &_Myproxy->_Myfirstiter;
*_Pnext != 0; *_Pnext = (*_Pnext)->_Mynextiter)
(*_Pnext)->_Myproxy = 0;
_Myproxy->_Myfirstiter = 0;
}
#endif /* _ITERATOR_DEBUG_LEVEL == 2 */
}
这个是为什么呢
...全文
1032 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
赵4老师 2014-11-16
  • 打赏
  • 举报
回复
进程意外退出会在当前目录下产生‘core’文件或形如‘core.数字’的文件比如‘core.1234’ 使用命令 gdb 运行程序名 core或core.数字 进入gdb然后使用bt命令 可以查看进程意外退出前函数调用的堆栈,内容为从上到下列出对应从里层到外层的函数调用历史。 如果进程意外退出不产生core文件,参考“ulimit -c core文件最大块大小”命令
mujiok2003 2014-10-11
  • 打赏
  • 举报
回复
remove_if + erase手法, 不要自己写循环干这个
xydp1987108 2014-10-11
  • 打赏
  • 举报
回复
不清楚 TaskNode如何定义的,你可以尝试下直接用迭代器判断改成如下: for(;Iter1!=CGlobal::s_resMng._taskList.end();Iter1++) { if(*Iter1 == name) //name就是对应我要删的那个选项 { Iter1 = CGlobal::s_resMng._taskList.erase(Iter1); //此处出现bug 20141009 break; } }
huangdigege 2014-10-11
  • 打赏
  • 举报
回复
http://blog.csdn.net/daofengdeba/article/details/7865229
qq_16600121 2014-10-11
  • 打赏
  • 举报
回复
引用 10 楼 zhao4zhong1 的回复:
崩溃的时候在弹出的对话框按相应按钮进入调试,按Alt+7键查看Call Stack里面从上到下列出的对应从里层到外层的函数调用历史。双击某一行可将光标定位到此次调用的源代码或汇编指令处。
崩溃的时候没有弹出对话框,只是if判断错误直接跳出循环,也就是erase没有完全执行完就退出了而且erase后面程序的都不执行了
qq_16600121 2014-10-11
  • 打赏
  • 举报
回复
引用 8 楼 xydp1987108 的回复:
不清楚 TaskNode如何定义的,你可以尝试下直接用迭代器判断改成如下: for(;Iter1!=CGlobal::s_resMng._taskList.end();Iter1++) { if(*Iter1 == name) //name就是对应我要删的那个选项 { Iter1 = CGlobal::s_resMng._taskList.erase(Iter1); //此处出现bug 20141009 break; } }
因为我的tasklist里面push的是一个结构体,所以不能直接用iter来判断
赵4老师 2014-10-11
  • 打赏
  • 举报
回复
崩溃的时候在弹出的对话框按相应按钮进入调试,按Alt+7键查看Call Stack里面从上到下列出的对应从里层到外层的函数调用历史。双击某一行可将光标定位到此次调用的源代码或汇编指令处。
qq_16600121 2014-10-10
  • 打赏
  • 举报
回复
,我单步跟踪了,是因为orphan_range里面的while循环中_ptr出的错误,本该在第四次循环结束,但是它却没有结束继续执行,在第六次,下面的if判断失败所以崩溃,但是还是不知道是什么原因,有谁知道哪个orphan_range具体的作用是什么吗
qq_16600121 2014-10-10
  • 打赏
  • 举报
回复
引用 2 楼 lovesmiles 的回复:
for(;Iter1!=CGlobal::s_resMng._taskList.end();Iter1++) { TaskNode* p= *Iter1; if(p->Task == name) //name就是对应我要删的那个选项 { CGlobal::s_resMng._taskList.erase(Iter1); //此处出现bug 20141009 break; } } 典型的stl使用错误 ,你都删了别人了,还怎么iter1++? 改成如楼上的. for(;Iter1!=CGlobal::s_resMng._taskList.end();Iter1++) { TaskNode* p= *Iter1; if(p->Task == name) //name就是对应我要删的那个选项 { Iter1 = CGlobal::s_resMng._taskList.erase(Iter1); //此处出现bug 20141009 break; } }
不行,不管怎样,程序进入erase之后就在里面戛然而止了没有跳出来
qq_16600121 2014-10-10
  • 打赏
  • 举报
回复
引用 1 楼 xydp1987108 的回复:
CGlobal::s_resMng._taskList.erase(Iter1); 删除元素后迭代器失效 可改为iter1 = CGlobal::s_resMng._taskList.erase(Iter1);试下
我开始都试过了,不行,还是存在
taodm 2014-10-10
  • 打赏
  • 举报
回复
楼主,认真去啃《effective stl》后再用stl吧,真的。
勤奋的小游侠 2014-10-10
  • 打赏
  • 举报
回复
for(;Iter1!=CGlobal::s_resMng._taskList.end();Iter1++) { TaskNode* p= *Iter1; if(p->Task == name) //name就是对应我要删的那个选项 { CGlobal::s_resMng._taskList.erase(Iter1); //此处出现bug 20141009 break; } } 典型的stl使用错误 ,你都删了别人了,还怎么iter1++? 改成如楼上的. for(;Iter1!=CGlobal::s_resMng._taskList.end();Iter1++) { TaskNode* p= *Iter1; if(p->Task == name) //name就是对应我要删的那个选项 { Iter1 = CGlobal::s_resMng._taskList.erase(Iter1); //此处出现bug 20141009 break; } }
xydp1987108 2014-10-10
  • 打赏
  • 举报
回复
CGlobal::s_resMng._taskList.erase(Iter1); 删除元素后迭代器失效 可改为iter1 = CGlobal::s_resMng._taskList.erase(Iter1);试下

64,637

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧