[C++] STL容器中erase方法的不同陷阱 - 蘭陵N散記
STL中的容器都有erase方法,容器的存储分为顺序存储(如vector)与链式存储(如list,map)。先以map为例:
typedef std::map<std::string, std::string> TStrMap; typedef TStrMap::iterator TStrMapIter; TStrMap strmap; TStrMapIter iter = strmap.find("somekey"); strmap.erase(iter);这样使用erase方法没有任何问题,删除一个单结节之后,stl中的iterator都是与其中的数据元素关联的,关联的元素删除之后,iter已就失效,iter理解为指向元素的指针,那删除之后可以简单理解为已是一个野指针。
但有时我们一不注意,却会这样使用,这是错误的:
for(TStrMapIter iter= strmap.begin(); iter!= strmap.end();++iter) { if ("somevalue" == iter->second ) { strmap.erase(iter); } } iter所指的元素删除之后,++iter是错误的,会导致程序的未知结果,iter一般是不会移到指向下一个元素。
对于map与list这样的链式存储结构。我们一般可以有两种解决办法:
方法一
使用erase(iter++),因为iter2 = iter++是iter先移到指向下一个节点,而iter2还是指向当前的节点。注意理解iter++与++iter的区别。
for(TStrMapIter iter= strmap.begin(); iter!= strmap.end();) { if ("somevalue" == iter->second ) { strmap.erase(iter++); }