原文网址:http://blog.csdn.net/zengraoli/article/details/8905334

关于内存泄露的,今天无意想到,网上找了一下

 

本篇blog附带的所有工具和代码下载地址如下:

http://download.csdn.net/detail/zengraoli/5348827

文中的memcheck晚点的时候在把它打包成dll

一、使用Dbgview.exe

不多数都是用的Dbgview.exe,话说还不错,我一直想找的仅仅是一个检测内存泄露的class,没想到csdn上面问,找到了这么一个工具,参看csdn论坛链接http://bbs.csdn.net/topics/390452307

来个测试工程:

  1. #include <iostream>
  2. #include "string"
  3. #include "vector"
  4. using namespace std;
  5. int main()
  6. {
  7. {
  8. char *str;
  9. str = new char[100 + 1];
  10. strcpy(str, "zengraoli");
  11. cout << str << endl;
  12. }
  13. _CrtDumpMemoryLeaks();   // 内存泄露检测
  14. return 0;
  15. }

Ctrl+F5后,在Dbgview.exe中出现了下面的信息:

Detected memory leaks

这个是提示

上面的测试不方便的地方:

但在这上面显然有不太好的地方,比如我需要知道哪一行导致的内存泄露,所以参考csdn blog的一篇文章:http://blog.csdn.net/iuhsihsow/article/details/8492363

再次修改:

  1. #include "stdafx.h"
  2. #include <iostream>
  3. #include "string"
  4. #include "vector"
  5. using namespace std;
  6. #ifdef  _DEBUG
  7. #define _CRTDBG_MAP_ALLOC
  8. #include <stdlib.h>
  9. #include <crtdbg.h>
  10. #define newEx   new(_NORMAL_BLOCK, __FILE__, __LINE__)
  11. #endif
  12. inline void EnableMemLeakCheck()
  13. {
  14. _CrtSetDbgFlag(_CrtSetDbgFlag(_CRTDBG_REPORT_FLAG) | _CRTDBG_LEAK_CHECK_DF);
  15. }
  16. int _tmain(int argc, _TCHAR* argv[])
  17. {
  18. EnableMemLeakCheck();
  19. char *str = newEx char[9 + 1];
  20. cout << str << endl;
  21. return 0;
  22. }

Ctrl+F5后,在Dbgview.exe中出现了下面的信息:

可以看到正是25行的地方导致内存泄露的

二、不使用Dbgview.exe,直接使用class

参考文章:http://www.cnblogs.com/FCoding/archive/2012/07/04/2576877.html

Code没来得及细看,能用就是了^_^,方便就行,枉自猜测一下原理----------重载了new和delete,对他俩进行一个计数,并记下行数,两个不为偶数,则就是代表已经出现内存泄露了

MemCheck.h:

  1. #ifndef MEMCHECK_H
  2. #define MEMCHECK_H
  3. #include <cstddef>  // for size_t
  4. // Hijack the new operator (both scalar and array versions)
  5. void* operator new(std::size_t, const char*, long);
  6. void* operator new[](std::size_t, const char*, long);
  7. #define new new (__FILE__, __LINE__)
  8. extern bool traceFlag;
  9. #define TRACE_ON() traceFlag = true
  10. #define TRACE_OFF() traceFlag = false
  11. extern bool activeFlag;
  12. #define MEM_ON() activeFlag = true
  13. #define MEM_OFF() activeFlag = false
  14. #endif

MemCheck.cpp:

  1. #include <cstdio>
  2. #include <cstdlib>
  3. #include <cassert>
  4. using namespace std;
  5. #undef new
  6. // Global flags set by macros in MemCheck.h
  7. bool traceFlag  = true;
  8. bool activeFlag = false;
  9. namespace
  10. {
  11. // Memory map entry type
  12. struct Info
  13. {
  14. void* ptr;
  15. const char* file;
  16. long  line;
  17. };
  18. // Memory map data
  19. const  size_t MAXPTRS = 10000u;
  20. Info   memMap[MAXPTRS];
  21. size_t nptrs = 0;
  22. // Searches the map for an address
  23. int findPtr(void* p)
  24. {
  25. for (int i = 0; i < nptrs; ++i)
  26. {
  27. if (memMap[i].ptr == p)
  28. {
  29. return i;
  30. }
  31. }
  32. return -1;
  33. }
  34. void delPtr(void* p)
  35. {
  36. int pos = findPtr(p);
  37. assert(p >= 0);
  38. // Remove pointer from map
  39. for (size_t i = pos; i < nptrs-1; ++i)
  40. {
  41. memMap[i] = memMap[i+1];
  42. }
  43. --nptrs;
  44. }
  45. // Dummy type for static destructor
  46. struct Sentinel
  47. {
  48. ~Sentinel()
  49. {
  50. if (nptrs > 0)
  51. {
  52. printf("Leaked memory at:\n");
  53. for (size_t i = 0; i < nptrs; ++i)
  54. {
  55. printf("\t%p (file: %s, line %ld)\n",
  56. memMap[i].ptr, memMap[i].file, memMap[i].line);
  57. }
  58. }
  59. else
  60. {
  61. printf("No user memory leaks!\n");
  62. }
  63. }
  64. };
  65. // Static dummy object
  66. Sentinel s;
  67. } // End anonymous namespace
  68. // Overload scalar new
  69. void* operator new(size_t siz, const char* file,
  70. long line)
  71. {
  72. void* p = malloc(siz);
  73. if (activeFlag)
  74. {
  75. if (nptrs == MAXPTRS)
  76. {
  77. printf("memory map too small (increase MAXPTRS)\n");
  78. exit(1);
  79. }
  80. memMap[nptrs].ptr = p;
  81. memMap[nptrs].file = file;
  82. memMap[nptrs].line = line;
  83. ++nptrs;
  84. }
  85. if (traceFlag)
  86. {
  87. printf("Allocated %u bytes at address %p ", siz, p);
  88. printf("(file: %s, line: %ld)\n", file, line);
  89. }
  90. return p;
  91. }
  92. // Overload array new
  93. void* operator new[](size_t siz, const char* file,
  94. long line)
  95. {
  96. return operator new(siz, file, line);
  97. }
  98. // Override scalar delete
  99. void operator delete(void* p)
  100. {
  101. if (findPtr(p) >= 0)
  102. {
  103. free(p);
  104. assert(nptrs > 0);
  105. delPtr(p);
  106. if (traceFlag)
  107. {
  108. printf("Deleted memory at address %p\n", p);
  109. }
  110. }
  111. else if (!p && activeFlag)
  112. {
  113. printf("Attempt to delete unknown pointer: %p\n", p);
  114. }
  115. }
  116. // Override array delete
  117. void operator delete[](void* p)
  118. {
  119. operator delete(p);
  120. }

那哥们的测试工程,挺不错的,有3种情况:

  1. #include "stdafx.h"
  2. #include <iostream>
  3. #include <vector>
  4. #include <cstring>
  5. #include "MemCheck.h"   // Must appear last!
  6. using namespace std;
  7. void Test()
  8. {
  9. int *i = new int(0);
  10. }
  11. class MyClass
  12. {
  13. private:
  14. int *p;
  15. public:
  16. MyClass()
  17. {
  18. if(p != NULL)
  19. {
  20. p = new int(0);
  21. }
  22. }
  23. ~MyClass()
  24. {
  25. if(p != NULL)
  26. {
  27. delete p;
  28. p = NULL;
  29. }
  30. }
  31. };
  32. void Test2()
  33. {
  34. int *i = NULL;  // better for read
  35. i = new int(0);
  36. int *&y = i;    // pointer's reference
  37. delete i;
  38. MyClass *pMyClass = new MyClass();
  39. std::vector<MyClass*> myClasses;
  40. myClasses.push_back(new MyClass());
  41. myClasses.push_back(new MyClass());
  42. std::vector<void*> myVector;
  43. myVector.push_back(new MyClass());
  44. myVector.push_back(new MyClass());
  45. delete (MyClass *)(myVector.at(0));
  46. delete myVector.at(1); // memory leak
  47. }
  48. class Foo
  49. {
  50. char* s;
  51. public:
  52. Foo(const char*s )
  53. {
  54. this->s = new char[strlen(s) + 1];
  55. strcpy(this->s, s);
  56. }
  57. ~Foo()
  58. {
  59. delete [] s;
  60. }
  61. };
  62. void Test3()
  63. {
  64. cout << "hello\n";
  65. int* p = new int;
  66. delete p;
  67. int* q = new int[3];
  68. delete [] q;
  69. /**//*delete r;*/
  70. vector<int> v;
  71. v.push_back(1);
  72. Foo s("goodbye");
  73. }
  74. int main()
  75. {
  76. TRACE_OFF();
  77. MEM_ON();
  78. Test();
  79. Test2();
  80. Test3();
  81. MEM_OFF();
  82. }

在我编译的时候,会出现一下提示:

运行的时候出现:

对这个cpp的使用说明:

1、使用时在工程中加入在MemCheck.h,而且这个.h文件应该放在所以头文件的后边,因为里面有这么一句代码:#undef new

2、用MEM_ON()和MEM_OFF()来打开和关闭检测

3、TRACE_ON()和TRACE_OFF()用来打开或关闭检测结果的输出(上面的测试代码中使用没做检测结果的输出)

4、可以检测代码中使用了流、标准容器,以及某个类的构造函数分配了空间

【转】c++内存泄露检测,长文慎入!的更多相关文章

  1. memwatch内存泄露检测工具

    工具介绍 官网 http://www.linkdata.se/sourcecode/memwatch/ 其功能如下官网介绍,挑选重点整理: 1. 号称功能: 内存泄露检测 (检测未释放内存, 即 动态 ...

  2. Visual C++内存泄露检测—VLD工具使用说明[转]

    Visual C++内存泄露检测—VLD工具使用说明 一.        VLD工具概述 Visual Leak Detector(VLD)是一款用于Visual C++的免费的内存泄露检测工具.他的 ...

  3. Visual C++内存泄露检测—VLD工具使用说明

    一.        VLD工具概述 Visual Leak Detector(VLD)是一款用于Visual C++的免费的内存泄露检测工具.他的特点有:可以得到内存泄漏点的调用堆栈,如果可以的话,还 ...

  4. vld(Visual Leak Detector) 内存泄露检测工具

    初识Visual Leak Detector 灵活自由是C/C++语言的一大特色,而这也为C/C++程序员出了一个难题.当程序越来越复 杂时,内存的管理也会变得越加复杂,稍有不慎就会出现内存问题.内存 ...

  5. Android内存泄露---检测工具篇

    内存使用是程序开发无法回避的一个问题.如果我们毫不在意肆意使用,总有一天会为此还账,且痛不欲生...所以应当防患于未然,把内存使用细化到平时的每一行代码中. 内存使用概念较大,本篇先讲对已有app如何 ...

  6. 【YFMemoryLeakDetector】人人都能理解的 iOS 内存泄露检测工具类

    背景 即使到今天,iOS 应用的内存泄露检测,仍然是一个很重要的主题.我在一年前,项目中随手写过一个简单的工具类,当时的确解决了大问题.视图和控制器相关的内存泄露,几乎都不存在了.后来想着一直就那个工 ...

  7. vld,Bounds Checker,memwatch,mtrace,valgrind,debug_new几种内存泄露检测工具的比较,Valgrind Cheatsheet

    概述 内存泄漏(memory leak)指由于疏忽或错误造成程序未能释放已经不再使用的内存的情况,在大型的.复杂的应用程序中,内存泄漏是常见的问题.当以前分配的一片内存不再需要使用或无法访问时,但是却 ...

  8. C++Builder 内存泄露检测

    C++Builder 内存泄露检测 CodeGuard http://bbs.2cto.com/read.php?tid=179933 XE新版里 ReportMemoryLeaksOnShutdow ...

  9. C/C++内存泄露检测

    以下测试基于的gcc版本: gcc (Ubuntu 4.8.4-2ubuntu1~14.04) 4.8.4Copyright (C) 2013 Free Software Foundation, In ...

随机推荐

  1. hdu 4869

    一个机智题,可惜比赛的时候没有机智出来 #include<cstdio> #include<cstring> #include<cmath> #include< ...

  2. uva 11375

    思路是刘书上的 但是个高精度  java 大数 ~~ import java.util.*; import java.io.*; import java.math.BigInteger; public ...

  3. crud springmvc

    实体类:Student.java package demo.entity; public class Student { private int id; private String name; pr ...

  4. tomcat 解析(二)-消息处理过程

    接下来我们应该去了解一下 tomcat 是如何处理jsp和servlet请求的. 1.  我们以一个具体的例子,来跟踪TOMCAT, 看看它是如何把Request一层一层地递交给下一个容器, 并最后交 ...

  5. 利用Qemu Guest Agent (Qemu-ga) 实现 Openstack 监控平台

    经常使用vmWare的同学都知道有vmware-tools这个工具,这个安装在vm内部的工具,可以实现宿主机与虚拟机的通讯,大大增强了虚拟机的性能与功能, 如vmware现在的Unity mode下可 ...

  6. Strange java.lang.ArrayIndexOutOfBoundsException thrown on jetty startup

    http://stackoverflow.com/questions/26496338/strange-java-lang-arrayindexoutofboundsexception-thrown- ...

  7. 桥接模式(Bridge Pattern)

    1,定义           桥接模式(Bridge Pattern),也称为桥梁模式,其用意是将抽象化与实现化脱耦,使得两者可以独立的变化,它可以使软件系统沿着多个方向进行变化,而又不引入额外的复杂 ...

  8. 2010年山东省第一届ACM大学生程序设计竞赛 Balloons (BFS)

    题意 : 找联通块的个数,Saya定义两个相连是 |xa-xb| + |ya-yb| ≤ 1 ,但是Kudo定义的相连是 |xa-xb|≤1 并且 |ya-yb|≤1.输出按照两种方式数的联通块的各数 ...

  9. Oracle 6 - 锁和闩 - 锁类型

    Oracle锁大类 1.DML锁 (SELECT, INSERT, UPDATE, DELETE, MERGE是对数据库加的锁, 可能是行锁,也可能是表锁) 2.DDL锁 (Create, Alter ...

  10. cygwin如何断点续传

    对于Cygwin,如果想安装的东西比较多的话,推荐先选择“Download without installing”,下载完了再从本地安装. 好了,说关于断点续传.我所知道的是—— 网上有说法:下载失败 ...