1#include <iostream>2#include <map>3 4 using namespacestd;5 6 classA7 {8 Public:9typedef std::map<int,string>MyMap;Ten One voidMapinsert (intIstrings) A { - Map.insert (Std::make_pair (i, s)); - } the - voidDeletemap () - { - for(Mymap::iterator it = Map.begin (); It! = Map.end (); ++it) + { -Map.erase (it->First ); + } A } at Private: - myMap map; - }; - - intMain () - { in A; -A.mapinsert (1,"1"); toA.mapinsert (2,"2"); +A.mapinsert (3,"3"); -A.mapinsert (4,"4"); theA.mapinsert (5,"5"); * $ A.deletemap ();Panax Notoginseng - return 0; the}
There is no problem with compiling the code above, but using Valgrind detection will prompt an error:
Valgrind--tool=memcheck--leak-check=full--track-origins=yes./test # ~/test ==723953== Memcheck, a memory error detector ==723953== Copyright (C) 2002-2012, and GNU GPL ' d, by Julian Seward et al. ==723953== Using Valgrind-3.8.1 and Libvex; Rerun with-h for copyright info ==723953== Command:./test ==723953== ==723953==Invalid Read of size 8 ==723953== at 0x3431c69e60:std::_rb_tree_increment (std::_rb_tree_node_base*) (tree.cc:60) ==723953== by 0X40131C:STD::_RB_TREE_ITERATOR<STD::p air<int const, std::string> >::operator++ () (In/home /thm/test/test) ==723953== by 0x40117c:a::d Eletemap () (in/home/thm/test/test) ==723953== by 0x400f4b:main (in/home/thm/test/test) ==723953== Address 0x4c580b8 is bytes inside a block of size + free ' d ==723953== at 0x4a06016:operator Delete (void*) (vg_replace_malloc.c:480) ==723953== by 0x401e23: __gnu_cxx::new_allocator<std::_rb_tree_node<std::p air<int const, std::string> >::d eallocate (STD::_RB_TREE_NODE<STD::p air<int const, std::string> >*, unsigned long) (in/home/ Thm/test/test) ==723953== by 0x401c99:std::_rb_tree<int, std::p air<int const, STD::STRING>, std::_select1st<std::p air& Lt;int Const, std::string>;, Std::less<int>, STD::ALLOCATOR<STD::p air<int const, std::string> > >::_m_put_node (STD::_RB_TREE_NODE<STD::p air<int const, std::string> >*) (in/home/thm/test/test) ==723953== by 0x401aa6:std::_rb_tree<int, std::p air<int const, STD::STRING>, std::_select1st<std::p air& Lt;int Const, std::string>;, Std::less<int>, STD::ALLOCATOR<STD::p air<int const, std::string> > >::_m_destroy_node (STD::_RB_TREE_NODE<STD::p air<int const, std::string> >*) (in/home/thm/test/ Test ==723953== by 0x401729:std::_rb_tree<int, std::p air<int const, STD::STRING>, std::_select1st<std::p air& Lt;int Const, std::string>;, Std::less<int>, STD::ALLOCATOR<STD::p air<int const, std::string> > >::erase (STD::_RB_TREE_ITERATOR<STD::p air<int const, std::string> >) (in/home/thm/test/test) ==723953== by 0x40134c:std::map<int, std::string, Std::less<int>, STD::ALLOCATOR<STD::p air<int Const, std::string> > >::erase (std::_rb_tree_iterator<std::p air<int const, std::string> >) (in/home/ Thm/test/test) ==723953== by 0x401170:a::d Eletemap () (in/home/thm/test/test) ==723953== by 0x400f4b:main (in/home/thm/test/test) ==723953== ==723953== Invalid Read of size 8 ==723953== at 0x3431c69e80:std::_rb_tree_increment (std::_rb_tree_node_base*) (tree.cc:68) ==723953== by 0X40131C:STD::_RB_TREE_ITERATOR<STD::p air<int const, std::string> >::operator++ () (In/home /thm/test/test) ==723953== by 0x40117c:a::d Eletemap () (in/home/thm/test/test) ==723953== by 0x400f4b:main (in/home/thm/test/test) ==723953== Address 0x4c580a8 is 8 bytes inside a block of size + free ' d ==723953== at 0x4a06016:operator Delete (void*) (vg_replace_malloc.c:480) ==723953== by 0x401e23: __gnu_cxx::new_allocator<std::_rb_tree_node<std::p air<int const, std::string> >::d eallocate (STD::_RB_TREE_NODE<STD::p air<int const, std::string> >*, unsigned long) (in/home/ Thm/test/test) ==723953== by 0x401c99:std::_rb_tree<int, std::p air<int const, STD::STRING>, std::_select1st<std::p air& Lt;int Const, std::string>;, Std::less<int>, STD::ALLOCATOR<STD::p air<int const, std::string> > >::_m_put_node (STD::_RB_TREE_NODE<STD::p air<int const, std::string> >*) (in/home/thm/test/test) ==723953== by 0x401aa6:std::_rb_tree<int, std::p air<int const, STD::STRING>, std::_select1st<std::p air& Lt;int Const, std::string>;, Std::less<int>, STD::ALLOCATOR<STD::p air<int const, std::string> > >::_m_destroy_node (STD::_RB_TREE_NODE<STD::p air<int const, std::string> >*) (in/home/thm/test/ Test ==723953== by 0x401729:std::_rb_tree<int, std::p air<int const, STD::STRING>, std::_select1st<std::p air& Lt;int Const, std::string>;, Std::less<int>, STD::ALLOCATOR<STD::p air<int const, std::string> > >::erase (STD::_RB_TREE_ITERATOR<STD::p air<int const, std::string> >) (in/home/thm/test/test) ==723953== by 0x40134c:std::map<int, std::string, Std::less<int>, STD::ALLOCATOR<STD::p air<int Const, std::string> > >::erase (std::_rb_tree_iterator<std::p air<int const, std::string> >) (in/home/ Thm/test/test) ==723953== by 0x401170:a::d Eletemap () (in/home/thm/test/test) ==723953== by 0x400f4b:main (in/home/thm/test/test) ==723953== ==723953== ==723953== HEAP SUMMARY: ==723953== in with exit:0 bytes in 0 blocks ==723953== Total Heap Usage:10 Allocs, frees, 370 bytes allocated ==723953== ==723953== all heap blocks were freed--no leaks is possible ==723953== ==723953== for counts of detected and suppressed errors, rerun with:-V ==723953== ERROR Summary:8 errors from 2 contexts (Suppressed:6 from 6)
|
Why?
This code can implement functional requirements, but robustness is not good, assuming that after map.erase to use the map of the current iterator, that is,
void Deletemap () { for (Mymap::iterator it = Map.begin (); It! = Map.end (); ++it) { map.erase (it- First ); << "map.first=" << it->first << " map.second=" << It->second << std::endl; } }
The code will run out of error because the object it is pointing to has been deleted.
To avoid this error in the program, we should ensure that the iterator has shifted forward before the object pointed to by iterator is deleted .
The program can be changed as follows:
void Deletemap () { for (Mymap::iterator it = Map.begin (); it! = map.end ();) { map.erase (it++-> First ); } }
Or
void Deletemap () { for (Mymap::iterator it = Map.begin (); it! = map.end () ;) { int i = it-> first; + +it; Map.erase (i); } }
For loop delete element in map, valgrind detection hint error:invalid read of size 8