c++ - std::map iterate and delete valgrind errors -


i have simple program deletes items in std::map while iterating on map. if not wrong forward iterators not invalidated erase in map. valgrind throws invalid read errors. can explain why.

#include <map> #include <iostream>  typedef std::map<std::string, int> sourcemap; int main(int argc, char *argv[]) {     sourcemap sourcemap;     sourcemap["item1"] = 1;     sourcemap["item2"] = 2;     sourcemap["item3"] = 3;     sourcemap["item4"] = 4;       for(sourcemap::const_iterator it=sourcemap.begin(); != sourcemap.end(); ++it)     {         sourcemap.erase(it->first);     } } 

valgrind errors:

==31703== invalid read of size 8 ==31703==    @ 0x3851069e60: std::_rb_tree_increment(std::_rb_tree_node_base*) (in /usr/lib64/libstdc++.so.6.0.13) ==31703==    0x4013d6: std::_rb_tree_const_iterator<std::pair<std::string const, int> >::operator++() (stl_tree.h:259) ==31703==    0x40106b: main (map_iterator.cpp:14) ==31703==  address 0x4c2c0b8 24 bytes inside block of size 48 free'd ==31703==    @ 0x4a0545f: operator delete(void*) (vg_replace_malloc.c:387) ==31703==    0x402821: __gnu_cxx::new_allocator<std::_rb_tree_node<std::pair<std::string const, int> > >::deallocate(std::_rb_tree_node<std::pair<std::string const, int> >*, unsigned long) (new_allocator.h:95) ==31703==    0x402103: std::_rb_tree<std::string, std::pair<std::string const, int>, std::_select1st<std::pair<std::string const, int> >, std::less<std::string>, std::allocator<std::pair<std::string const, int> > >::_m_put_node(std::_rb_tree_node<std::pair<std::string const, int> >*) (stl_tree.h:363) ==31703==    0x4017d0: std::_rb_tree<std::string, std::pair<std::string const, int>, std::_select1st<std::pair<std::string const, int> >, std::less<std::string>, std::allocator<std::pair<std::string const, int> > >::_m_destroy_node(std::_rb_tree_node<std::pair<std::string const, int> >*) (stl_tree.h:384) ==31703==    0x4027ab: std::_rb_tree<std::string, std::pair<std::string const, int>, std::_select1st<std::pair<std::string const, int> >, std::less<std::string>, std::allocator<std::pair<std::string const, int> > >::erase(std::_rb_tree_iterator<std::pair<std::string const, int> >) (stl_tree.h:1348) ==31703==    0x401ff2: std::_rb_tree<std::string, std::pair<std::string const, int>, std::_select1st<std::pair<std::string const, int> >, std::less<std::string>, std::allocator<std::pair<std::string const, int> > >::erase(std::_rb_tree_iterator<std::pair<std::string const, int> >, std::_rb_tree_iterator<std::pair<std::string const, int> >) (stl_tree.h:1388) ==31703==    0x4016a7: std::_rb_tree<std::string, std::pair<std::string const, int>, std::_select1st<std::pair<std::string const, int> >, std::less<std::string>, std::allocator<std::pair<std::string const, int> > >::erase(std::string const&) (stl_tree.h:1374) ==31703==    0x40141c: std::map<std::string, int, std::less<std::string>, std::allocator<std::pair<std::string const, int> > >::erase(std::string const&) (stl_map.h:582) ==31703==    0x40105c: main (map_iterator.cpp:16) ==31703== ==31703== ==31703== heap summary: ==31703==     in use @ exit: 0 bytes in 0 blocks ==31703==   total heap usage: 8 allocs, 8 frees, 312 bytes allocated ==31703== ==31703== heap blocks freed -- no leaks possible 

this has been discussed death. must not use invalid iterators. write this:

for(sourcemap::const_iterator = sourcemap.begin();     != sourcemap.end();  /* no hoist */    /* no increment */ ) {     sourcemap.erase(it++); } 

alternatively:

// before {     = sourcemap.erase(it); } 

alternatively yet (since don't have conditions on erasing):

sourcemap.clear(); 

Comments

Popular posts from this blog

apache - Remove .php and add trailing slash in url using htaccess not loading css -

javascript - jQuery show full size image on click -