Remove elements from map in the For loop valgrind detection hint error:invalid read of size 8_c language

Source: Internet
Author: User
Tags valgrind

Don't say much nonsense, first look at the following section of code

#include <iostream>
#include <map>
using namespace std;
Class A
{public
:
typedef std::map<int, string> Mymap;
void Mapinsert (int i, string s)
{
Map.insert (Std::make_pair (i, s));
}
void Deletemap ()
{for
(mymap::iterator it = Map.begin (); it!= map.end (); ++it)
{
map.erase (it- >first);
}
Private:
mymap map;
int main ()
{
a A;
A.mapinsert (1, "1");
A.mapinsert (2, "2");
A.mapinsert (3, "3");
A.mapinsert (4, "4");
A.mapinsert (5, "5");
A.deletemap ();
return 0;
}

There is no problem with compiling the above code, but using Valgrind detection prompts for an error:

Valgrind--tool=memcheck--leak-check=full--track-origins=yes/test # ~/test ==723953==, a memcheck error memory or ==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 0x 3431c69e60:std::_rb_tree_increment (std::_rb_tree_node_base*) (tree.cc:60) ==723953== by 0x40131c:std::_rb_tree_ ITERATOR&LT;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 0x4c580
B8 is bytes inside a block of size A/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_tr Ee<int, std::p air<int const, STD::STRING&GT, STD::_SELECT1ST&LT;STD::p air<int const, std::string>, Std::less<int&gt, STD::ALLOCATOR&LT;STD::p air<int const, std::string> > >::_m_put_node (std::_Rb_ TREE_NODE&LT;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&GT, STD::_SELECT1ST&LT;STD::p air<int const, std::string> > , Std::less<int&gt, STD::ALLOCATOR&LT;STD::p air<int const, std::string> > >::_m_destroy_node (std::_ RB_TREE_NODE&LT;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&GT, STD::_SELECT1ST&LT;STD::p air<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&LT;STD:: Pair<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_in Crement (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 are 8 bytes inside a block of Size d ' ==723953== at 0x4a06016:operator DeleTe (void*) (vg_replace_malloc.c:480) ==723953== by 0x401e23: __gnu_cxx::new_allocator<std::_rb_tree_node<std:: Pair<int const, std::string> >::d eallocate (STD::_RB_TREE_NODE&LT;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&gt, STD::_SELECT1ST&LT;STD::p air<int const, std::string>, Std::less<int>, std:: ALLOCATOR&LT;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&GT, STD::_SELECT1ST&LT;STD::p air<int const, std::string>, Std::less<int>, std:: ALLOCATOR&LT;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&GT, STD::_SELECT1ST&LT;STD::p air<int const, std: :string>, Std::less<int&gt, STD::ALLOCATOR&LT;STD::p air<int const, std::string> > >::erase ( STD::_RB_TREE_ITERATOR&LT;STD::p air<int const, std::string> >) (in/home/thm/test/test) ==723953== by 0x40134c:std::map<int, std::string, Std::less<int&gt, STD::ALLOCATOR&LT;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 Use, exit:0 bytes in 0 blocks ==723953== total HEAP usage: Allocs, frees, 370 bytes allocated ==723953== ==723953== all heap blocks-were freed--no leaks are possible 953== ==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 the map's current iterator is reused after map.erase, that is

void Deletemap ()
{for
(mymap::iterator it = Map.begin (); it!= map.end (); ++it)
{
map.erase (it-> a);
Std::cout << "map.first=" << it->first << "map.second=" << it->second << std::endl;< c6/>}
}

The code will run incorrectly because the object it is currently pointing to has been deleted.

To avoid this error in the program, we should ensure that the iterator has shifted forward one before the object that iterator points to is deleted.

The procedure can be changed as follows:

void Deletemap ()
{for
(mymap::iterator it = Map.begin (); it!= map.end ();)
{
map.erase (it++-> a);

Or

void Deletemap ()
{for
(mymap::iterator it = Map.begin (); it!= map.end ();)
{
int i = it->first;
   ++it;
Map.erase (i);
}
}

The above is described in the For loop to remove elements from the map Valgrind detection hint Error:invalid read of size 8, I hope to help you, if you have any questions please give me a message, small series will promptly reply to everyone. Here also thank you very much for the cloud Habitat Community website support!

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.