STL容器遍历删除时诡异的erase
2012-05-29 20:35
155 查看
STL容器遍历删除时诡异的erase
2011-07-07 13:02
2011-07-07 13:02
我们知道STL中结点类容器(如:list,hash_map)遍历时进行删除时,需要这样做: for(list<int>::iterator iter = m_list.begin(); iter != m_list.end(); ) { if(需要删除) { m_list.erase(iter++); } else ++iter; } 而不能这样: for(list<int>::iterator iter = m_list.begin(); iter != m_list.end(); ++iter) { if(需要删除) { m_list.erase(iter); } } 为什么呢? 以STL list为例: iterator的相关操作 _Self& operator++() { this->_M_incr(); return *this; } _Self operator++(int) { _Self __tmp = *this; this->_M_incr(); return __tmp; //后缀++按照语意返回了++前的iterator, } void _M_incr() { _M_node = _M_node->_M_next; } //++的操作对于list结构来说,就是使iterator的_M_node指向下一个结点 iterator erase(iterator __position) { _List_node_base* __next_node = __position._M_node->_M_next; _List_node_base* __prev_node = __position._M_node->_M_prev; _Node* __n = (_Node*) __position._M_node; __prev_node->_M_next = __next_node; __next_node->_M_prev = __prev_node; //上面的代码把删除结点__position的前后结点串起来,而移除_positoin _STLP_STD::_Destroy(&__n->_M_data); //call T::~T() this->_M_node.deallocate(__n, 1); //释放结点内存 return iterator((_Node*)__next_node); } 分析代码我们可以看出,erase会deallocate__position的_M_node, 在__position上再进行++是错误的。 所以不能在m_list.erase(iter)后,进行iter++. 哪为什么m_list.erase(iter++)可以呢?为什么不能用m_list.erase(++iter)? 参照operator++的代码我们可以找到答案,iter++返回了++之前的iter值,erase使用这个值能正确进行__position的前后结点的串接及删除正确的结点,而++iter返回的是++之后的iter,所以m_list.erase(++iter)串接不正确,iter->_M_node也是失效的. 对于非结点类,如数组类的容器vector,string,deque,如果erase会返回下个有效的iterator,可以这样处理: for(vector<int>::iterator iter = m_vector.begin(); iter != m_vector.end();) { if(需要删除) { iter=m_vector.erase(iter); } else ++iter; } |
相关文章推荐
- 剖析STL容器遍历删除时诡异的erase(iter++) http://bbs.csdn.net/topics/100044107
- 剖析STL容器遍历删除时诡异的erase(iter++)
- STL容器遍历删除时诡异的erase
- STL中容器使用erase()遍历删除
- c++ stl容器vector删除(erase),遍历等基本用法介绍及头文件
- STL容器的遍历删除操作erase
- c++ stl容器vector删除(erase),遍历等基本用法介绍及头文件
- stl容器在循环遍历中删除元素的方式
- STL中用ERASE()方法遍历删除元素
- STL中用erase()方法遍历删除元素
- STL中用ERASE()方法遍历删除元素
- STL中用erase()方法遍历删除元素
- C++ STL容器遍历删除元素的方法
- list(链表)常用成员(顺序容器)----插入push_back,push_front,insert删除pop_back,pop_front,erase,clear遍历begin,end判空emp
- STL中用erase()方法遍历删除元素注意的问题
- STL中用erase()方法遍历删除元素
- STL容器中 存放指针与对象区别 遍历删除与释放操作
- STL容器中元素的删除erase()、remove()
- STL中用erase()方法遍历删除元素
- STL中用erase()方法遍历删除元素 .xml