原文网址: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. window.open被IE拦截的解决办法

    由于在使用window.open时,在很多情况下,弹出的窗口会被浏览器阻止,但若是使用a链接target='_blank',则不会,基于这一特点,自己封装了一个open方法: function ope ...

  2. 如何处理JSON中的特殊字符

    JSON 是适用于 Ajax 应用程序的一种有效格式,原因是它使 JavaScript 对象和字符串值之间得以快速转换.由于 Ajax 应用程序非常适合将纯文本发送给服务器端程序并对应地接收纯文本,相 ...

  3. 套题T5//各种树

    树(tree) [题目描述] 方方方种下了三棵树,一年后,第一棵树长出了n个节点. 方方方会向你提出m个询问,每个询问给出两个数i,j,你需要回答i号节点和j号节点在树上的距离. [输入数据] 第一行 ...

  4. Python中itertools模块

    itertools模块包含创建有效迭代器的函数,可以用各种方式对数据进行循环操作,此模块中的所有函数返回的迭代器都可以与for循环语句以及其他包含迭代器(如生成器和生成器表达式)的函数联合使用. ch ...

  5. QTP之delphi试用感想一(自动化测试)

    这两天一直在琢磨自动化测试,自动化测试,其实与单元测试有一些相同之处,单元测试的目的也是可以一次写,多次运行,对于测试驱动及后期维护真是有非常多的好处,用自动化测试工具也是如何,主要目的是为了回归测试 ...

  6. Centos硬件信息查看命令

    [root@yan-001 ~] # uname -a # 查看内核/操作系统/CPU信息的linux系统信息命令 [root@yan-001 ~] # head -n 1 /etc/issue # ...

  7. linux用VSFTP搭建FTP服务器

    一般在各种linux的发行版中,默认带有的ftp软件是vsftp,从各个linux发行版对vsftp的认可可以看出,vsftp应该是一款不错的ftp软件. sudo apt-get install v ...

  8. 使用 powershell 的 grep 过滤文本

    使用 powershell 的 grep 过滤文本 有个log文件,大小在4M左右,要求找出里面耗时超过100s 的记录.首先想到了强大的 grep ,那么就搞起. 先在网上找一下资料,这篇文章,有几 ...

  9. php命令行用法简介

    Php是一个非常流行的web服务端脚本语言.其实,php不仅仅可以在web服务器中充当重要角色.在命令行一样可以执行. 本文中,笔者为各位介绍下php在命令行中的使用方法. 1.  查看php的版本. ...

  10. android为应用程序添加退出动画

    原本想搞一个退出程序时,把前一个应用程序的VIEW或者截图抓过来为我用,以实现更复杂的动画效果,尝试了很多方法,但都有或多或少的缺陷,可惜最后失败了.不过也算有所得.写文以标记. 其实抓图在4.0以后 ...