The for loop deletes the elements in the map. The valgrind detection prompt is error: Invalid read of size 8, mapvalgrind.

Source: Internet
Author: User
Tags valgrind

The for loop deletes the elements in the map. The valgrind detection prompt is error: Invalid read of size 8, mapvalgrind.

 1 #include <iostream> 2 #include <map> 3  4 using namespace std; 5  6 class A 7 { 8     public: 9     typedef std::map<int, string> myMap;10     11     void mapInsert(int i, string s)12     {13         map.insert(std::make_pair(i, s));14     }15     16     void deleteMap()17     {18         for (myMap::iterator it = map.begin(); it != map.end(); ++it)19         {20             map.erase(it->first);21         }22     }23     private:24     myMap map;25 };26 27 int main()28 {29     A a;30     a.mapInsert(1, "1");31     a.mapInsert(2, "2");32     a.mapInsert(3, "3");33     a.mapInsert(4, "4");34     a.mapInsert(5, "5");35     36     a.deleteMap();37     38     return 0;39 }

The above code compilation and running are all correct, but valgrind 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: pair <int const, std: string >:: operator ++ () (in/home/thm/test)
= 723953 = by 0x40117C: A: deleteMap () (in/home/thm/test)
= 723953 = by 0x400F4B: main (in/home/thm/test)
==723953 = Address 0x4c580b8 is 24 bytes inside a block of size 48 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: pair <int const, std: string >> :: deallocate (std: _ Rb_tree_node <std: pair <int const, std: string> *, unsigned long) (in/home/thm/test)
= 723953 = by 0x401C99: std: _ Rb_tree <int, std: pair <int const, std: string>, std: _ Select1st <std :: pair <int const, std: string >>, std: less <int>, std: allocator <std: pair <int const, std :: string >>::_ M_put_node (std: _ Rb_tree_node <std: pair <int const, std: string >> *) (in/home/thm/test)
= 723953 = by 0x401AA6: std: _ Rb_tree <int, std: pair <int const, std: string>, std: _ Select1st <std :: pair <int const, std: string >>, std: less <int>, std: allocator <std: pair <int const, std :: string >>>:: _ M_destroy_node (std: _ Rb_tree_node <std: pair <int const, std: string >> *) (in/home/thm/test)
= 723953 = by 0x401729: std: _ Rb_tree <int, std: pair <int const, std: string>, std: _ Select1st <std:: pair <int const, std: string >>, std: less <int>, std: allocator <std: pair <int const, std :: string >>:: erase (std: _ Rb_tree_iterator <std: pair <int const, std: string>) (in/home/thm/test)
= 723953 = by 0x40134C: std: map <int, std: string, std: less <int>, std: allocator <std :: pair <int const, std: string >>:: erase (std: _ Rb_tree_iterator <std: pair <int const, std: string>) (in/home/thm/test)
= 723953 = by 0x401170: A: deleteMap () (in/home/thm/test)
= 723953 = by 0x400F4B: main (in/home/thm/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: pair <int const, std: string >:: operator ++ () (in/home/thm/test)
= 723953 = by 0x40117C: A: deleteMap () (in/home/thm/test)
= 723953 = by 0x400F4B: main (in/home/thm/test)
==723953 = Address 0x4c580a8 is 8 bytes inside a block of size 48 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: pair <int const, std: string >> :: deallocate (std: _ Rb_tree_node <std: pair <int const, std: string> *, unsigned long) (in/home/thm/test)
= 723953 = by 0x401C99: std: _ Rb_tree <int, std: pair <int const, std: string>, std: _ Select1st <std :: pair <int const, std: string >>, std: less <int>, std: allocator <std: pair <int const, std :: string >>::_ M_put_node (std: _ Rb_tree_node <std: pair <int const, std: string >> *) (in/home/thm/test)
= 723953 = by 0x401AA6: std: _ Rb_tree <int, std: pair <int const, std: string>, std: _ Select1st <std :: pair <int const, std: string >>, std: less <int>, std: allocator <std: pair <int const, std :: string >>>:: _ M_destroy_node (std: _ Rb_tree_node <std: pair <int const, std: string >> *) (in/home/thm/test)
= 723953 = by 0x401729: std: _ Rb_tree <int, std: pair <int const, std: string>, std: _ Select1st <std:: pair <int const, std: string >>, std: less <int>, std: allocator <std: pair <int const, std :: string >>:: erase (std: _ Rb_tree_iterator <std: pair <int const, std: string>) (in/home/thm/test)
= 723953 = by 0x40134C: std: map <int, std: string, std: less <int>, std: allocator <std :: pair <int const, std: string >>:: erase (std: _ Rb_tree_iterator <std: pair <int const, std: string>) (in/home/thm/test)
= 723953 = by 0x401170: A: deleteMap () (in/home/thm/test)
= 723953 = by 0x400F4B: main (in/home/thm/test)
= 723953 =
= 723953 =
==723953 === heap summary:
= 723953 = in use at exit: 0 bytes in 0 blocks
= 723953 = total heap usage: 10 allocs, 10 frees, 370 bytes allocated
= 723953 =
= 723953 = All heap blocks were freed -- no leaks are 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 the robustness is not good. Assume that the current iterator of map is used again after map. erase, that is

    void deleteMap()    {        for (myMap::iterator it = map.begin(); it != map.end(); ++it)        {            map.erase(it->first);            std::cout << "map.first=" << it->first << "    map.second=" << it->second << std::endl;        }    }

An error occurs when the code is running, because the object to which it currently points has been deleted.

To avoid such errors, we should ensure that iterator has moved forward one before the object pointed to by iterator is deleted.

The program can be changed to the following:

    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);        }    }

 

Related Article

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.