废话不多说,先看下面一段代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
|
#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;
}
|
上述代码编译运行皆没有问题,但是用valgrind检测会提示错误:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
|
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/test)
==723953== by 0x40117C: A::deleteMap() (in /home/thm/test/test)
==723953== by 0x400F4B: main (in /home/thm/test/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/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/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/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/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/test)
==723953== by 0x401170: A::deleteMap() (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::pair< int const , std::string> >::operator++() (in /home/thm/test/test)
==723953== by 0x40117C: A::deleteMap() (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 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/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/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/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/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/test)
==723953== by 0x401170: A::deleteMap() (in /home/thm/test/test)
==723953== by 0x400F4B: main (in /home/thm/test/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?
此代码可以实现功能要求,但是健壮性并不好,假设在map.erase之后再次使用map当前的iterator,即
1
2
3
4
5
6
7
8
|
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;
}
}
|
代码运行就会出现错误,因为it目前指向的对象已经被删掉了。
为了避免程序出现这样的错误,我们应该保证在iterator指向的对象被删掉之前,iterator已经向前移位一。
程序改成如下即可:
1
2
3
4
5
6
7
|
void deleteMap()
{
for (myMap::iterator it = map.begin(); it != map.end();)
{
map.erase(it++->first);
}
}
|
或
1
2
3
4
5
6
7
8
9
|
void deleteMap()
{
for (myMap::iterator it = map.begin(); it != map.end();)
{
int i = it->first;
++it;
map.erase(i);
}
}
|
以上所述是小编给大家介绍的for循环中删除map中的元素valgrind检测提示error:Invalid read of size 8 ,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对服务器之家网站的支持!
原文链接:http://www.cnblogs.com/tang*0713/archive/2016/07/07/5651639.html