for循环中删除map中的元素valgrind检测提示error:Invalid read of size 8
废话不多说,先看下面一段代码
#include<iostream> #include<map> usingnamespacestd; classA { public: typedefstd::map<int,string>myMap; voidmapInsert(inti,strings) { map.insert(std::make_pair(i,s)); } voiddeleteMap() { for(myMap::iteratorit=map.begin();it!=map.end();++it) { map.erase(it->first); } } private: myMapmap; }; intmain() { Aa; a.mapInsert(1,"1"); a.mapInsert(2,"2"); a.mapInsert(3,"3"); a.mapInsert(4,"4"); a.mapInsert(5,"5"); a.deleteMap(); return0; }
上述代码编译运行皆没有问题,但是用valgrind检测会提示错误:
valgrind--tool=memcheck--leak-check=full--track-origins=yes./test#~/test ==723953==Memcheck,amemoryerrordetector ==723953==Copyright(C)2002-2012,andGNUGPL'd,byJulianSewardetal. ==723953==UsingValgrind-3.8.1andLibVEX;rerunwith-hforcopyrightinfo ==723953==Command:./test ==723953== ==723953==Invalidreadofsize8 ==723953==at0x3431C69E60:std::_Rb_tree_increment(std::_Rb_tree_node_base*)(tree.cc:60) ==723953==by0x40131C:std::_Rb_tree_iterator<std::pair<intconst,std::string>>::operator++()(in/home/thm/test/test) ==723953==by0x40117C:A::deleteMap()(in/home/thm/test/test) ==723953==by0x400F4B:main(in/home/thm/test/test) ==723953==Address0x4c580b8is24bytesinsideablockofsize48free'd ==723953==at0x4A06016:operatordelete(void*)(vg_replace_malloc.c:480) ==723953==by0x401E23:__gnu_cxx::new_allocator<std::_Rb_tree_node<std::pair<intconst,std::string>>>::deallocate(std::_Rb_tree_node<std::pair<intconst,std::string>>*,unsignedlong)(in/home/thm/test/test) ==723953==by0x401C99:std::_Rb_tree<int,std::pair<intconst,std::string>,std::_Select1st<std::pair<intconst,std::string>>,std::less<int>,std::allocator<std::pair<intconst,std::string>>>::_M_put_node(std::_Rb_tree_node<std::pair<intconst,std::string>>*)(in/home/thm/test/test) ==723953==by0x401AA6:std::_Rb_tree<int,std::pair<intconst,std::string>,std::_Select1st<std::pair<intconst,std::string>>,std::less<int>,std::allocator<std::pair<intconst,std::string>>>::_M_destroy_node(std::_Rb_tree_node<std::pair<intconst,std::string>>*)(in/home/thm/test/test) ==723953==by0x401729:std::_Rb_tree<int,std::pair<intconst,std::string>,std::_Select1st<std::pair<intconst,std::string>>,std::less<int>,std::allocator<std::pair<intconst,std::string>>>::erase(std::_Rb_tree_iterator<std::pair<intconst,std::string>>)(in/home/thm/test/test) ==723953==by0x40134C:std::map<int,std::string,std::less<int>,std::allocator<std::pair<intconst,std::string>>>::erase(std::_Rb_tree_iterator<std::pair<intconst,std::string>>)(in/home/thm/test/test) ==723953==by0x401170:A::deleteMap()(in/home/thm/test/test) ==723953==by0x400F4B:main(in/home/thm/test/test) ==723953== ==723953==Invalidreadofsize8 ==723953==at0x3431C69E80:std::_Rb_tree_increment(std::_Rb_tree_node_base*)(tree.cc:68) ==723953==by0x40131C:std::_Rb_tree_iterator<std::pair<intconst,std::string>>::operator++()(in/home/thm/test/test) ==723953==by0x40117C:A::deleteMap()(in/home/thm/test/test) ==723953==by0x400F4B:main(in/home/thm/test/test) ==723953==Address0x4c580a8is8bytesinsideablockofsize48free'd ==723953==at0x4A06016:operatordelete(void*)(vg_replace_malloc.c:480) ==723953==by0x401E23:__gnu_cxx::new_allocator<std::_Rb_tree_node<std::pair<intconst,std::string>>>::deallocate(std::_Rb_tree_node<std::pair<intconst,std::string>>*,unsignedlong)(in/home/thm/test/test) ==723953==by0x401C99:std::_Rb_tree<int,std::pair<intconst,std::string>,std::_Select1st<std::pair<intconst,std::string>>,std::less<int>,std::allocator<std::pair<intconst,std::string>>>::_M_put_node(std::_Rb_tree_node<std::pair<intconst,std::string>>*)(in/home/thm/test/test) ==723953==by0x401AA6:std::_Rb_tree<int,std::pair<intconst,std::string>,std::_Select1st<std::pair<intconst,std::string>>,std::less<int>,std::allocator<std::pair<intconst,std::string>>>::_M_destroy_node(std::_Rb_tree_node<std::pair<intconst,std::string>>*)(in/home/thm/test/test) ==723953==by0x401729:std::_Rb_tree<int,std::pair<intconst,std::string>,std::_Select1st<std::pair<intconst,std::string>>,std::less<int>,std::allocator<std::pair<intconst,std::string>>>::erase(std::_Rb_tree_iterator<std::pair<intconst,std::string>>)(in/home/thm/test/test) ==723953==by0x40134C:std::map<int,std::string,std::less<int>,std::allocator<std::pair<intconst,std::string>>>::erase(std::_Rb_tree_iterator<std::pair<intconst,std::string>>)(in/home/thm/test/test) ==723953==by0x401170:A::deleteMap()(in/home/thm/test/test) ==723953==by0x400F4B:main(in/home/thm/test/test) ==723953== ==723953== ==723953==HEAPSUMMARY: ==723953==inuseatexit:0bytesin0blocks ==723953==totalheapusage:10allocs,10frees,370bytesallocated ==723953== ==723953==Allheapblockswerefreed--noleaksarepossible ==723953== ==723953==Forcountsofdetectedandsuppressederrors,rerunwith:-v ==723953==ERRORSUMMARY:8errorsfrom2contexts(suppressed:6from6)
Why?
此代码可以实现功能要求,但是健壮性并不好,假设在map.erase之后再次使用map当前的iterator,即
voiddeleteMap() { for(myMap::iteratorit=map.begin();it!=map.end();++it) { map.erase(it->first); std::cout<<"map.first="<<it->first<<"map.second="<<it->second<<std::endl; } }
代码运行就会出现错误,因为it目前指向的对象已经被删掉了。
为了避免程序出现这样的错误,我们应该保证在iterator指向的对象被删掉之前,iterator已经向前移位一。
程序改成如下即可:
voiddeleteMap() { for(myMap::iteratorit=map.begin();it!=map.end();) { map.erase(it++->first); } }
或
voiddeleteMap() { for(myMap::iteratorit=map.begin();it!=map.end();) { inti=it->first; ++it; map.erase(i); } }
以上所述是小编给大家介绍的for循环中删除map中的元素valgrind检测提示error:Invalidreadofsize8,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对毛票票网站的支持!