#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(, "");
a.mapInsert(, "");
a.mapInsert(, "");
a.mapInsert(, "");
a.mapInsert(, ""); a.deleteMap(); return ;
}

上述代码编译运行皆没有问题,但是用valgrind检测会提示错误:

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,即

    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已经向前移位一。

程序改成如下即可:

    void deleteMap()
{
for (myMap::iterator it = map.begin(); it != map.end();)
{
map.erase(it++->first);
}
}

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

最新文章

  1. 时间戳与日期时间互转C语言
  2. Maven发布工程到公共库
  3. atitit.mp4&#160;视频文件多媒体格式结构详解
  4. Linux非root用户安装jdk和tomcat
  5. [BZOJ1477]青蛙的约会
  6. 读书笔记——《图解TCP/IP》(4/4)
  7. Ubuntu 13.10 64位 无法 安装 ia32-libs 解决办法
  8. Redis基础知识之——自定义封装单实例和普通类Redis
  9. JavaScript之Cookie讲解
  10. 建立名称server
  11. C# and android
  12. LeetCode_Palindrome Partitioning
  13. iOS 混合网页开发 问题
  14. 大量Javascript/JQuery学习教程电子书合集
  15. oracle12c之 单机12.1.0.1打补丁
  16. ubuntu opengl 开发
  17. 转 Web用户的身份验证及WebApi权限验证流程的设计和实现
  18. 第十节: 利用SQLServer实现Quartz的持久化和双机热备的集群模式 :
  19. linux执行python的脚本文件,提示提示No such file or directory
  20. js+jquery手写弹出提示框

热门文章

  1. IP地址加时间戳加3位随机数
  2. APPLE ID随意转区到US或者HK.不需要信用卡
  3. 【转】【Python学习】之哪些 Python 库让你相见恨晚?
  4. XSD文件详解(二)
  5. 自己定义Application的未捕获异常处理
  6. extendgcd模板
  7. 虚拟化构建二分图(BZOJ2080 题解+浅谈几道双栈排序思想的题)
  8. eclipse同一个工作空间下分开多个项目
  9. 学习Sharding JDBC 从入门到出门-1
  10. recognition rate generalization识别率 泛化