【转】c++内存泄露检测,长文慎入!

原文网址: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

来个测试工程:

[cpp] view plaincopyprint?

  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

再次修改:

[cpp] view plaincopyprint?

  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:

[cpp] view plaincopyprint?

  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:

[cpp] view plaincopyprint?

  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种情况:

[cpp] view plaincopyprint?

  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、可以检测代码中使用了流、标准容器,以及某个类的构造函数分配了空间

时间: 2024-10-12 11:43:50

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

长文慎入-探索Java并发编程与高并发解决方案

所有示例代码,请见/下载于https://github.com/Wasabi1234/concurrency #1 基本概念##1.1 并发同时拥有两个或者多个线程,如果程序在单核处理器上运行多个线程将交替地换入或者换出内存,这些线程是同时"存在"的,每个线程都处于执行过程中的某个状态,如果运行在多核处理器上,此时,程序中的每个线程都将分配到一个处理器核上,因此可以同时运行.##1.2 高并发( High Concurrency) 互联网分布式系统架构设计中必须考虑的因素之一,通常是指

内存泄露检测工具——LeakCanary

很简单:我们不是创建服务不是为了赚钱:我们赚钱是为了提供更好的服务.我们认为这才是做事的态度. 学习使用Java的同学都应该知道,Java的JVM给我们提供的垃圾回收机制是极为好用的.但是我们也很清楚,垃圾回收机制不是万能的,使用不当很容易造成内存泄露.之前我们也介绍过Java中常用的内存泄露检测工具MAT,目前Java程序最常用的内存分析工具应该是MAT(Memory Analyzer Tool),它是一个Eclipse插件,同时也有单独的RCP客户端. 不熟悉MAT的同学,或者对Java垃圾

linux c 内存泄露检测工具valgrind

Linux c/c++上常用内存泄露检测工具有valgrind, Rational  purify.Valgrind免费.Valgrind 可以在 32 位或 64 位 PowerPC/Linux 内核上工作.Valgrind工具包包含多个工具,如Memcheck,Cachegrind,Helgrind,  Callgrind,Massif.下面分别介绍个工具的作用:Memcheck  工具主要检查下面的程序错误:? 使用未初始化的内存 (Use of uninitialised  memory

C/C++内存泄露检测

gcc (Ubuntu 4.8.4-2ubuntu1~14.04) 4.8.4Copyright (C) 2013 Free Software Foundation, Inc.This is free software; see the source for copying conditions. There is NOwarranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 一.mtrace 1.介绍

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

1.VLD工具概述 Visual Leak Detector(VLD)是一款用于Visual C++的免费的内存泄露检测工具.他的特点有:可以得到内存泄漏点的调用堆栈,如果可以的话,还可以得到其所在文件及行号: 可以得到泄露内存的完整数据: 可以设置内存泄露报告的级别:并且是开源免费的. 2.VLD下载 http://www.codeproject.com/tools/visualleakdetector.asp 本文后附有vld1.0的工具包,下载解包后就可使用. 3.VLD安装 方法一: 解

内存泄露检测工具

VS2008的内存泄露检测功能有限,使用也有些局限性.今天因工作时间紧迫,工程繁琐,我最终选择了VLD(Visual Leak Detector).这个工具使用起来十分简单,只需要: (1)下载安装vld.安装过程中可以发现vld安装向导提示关闭VS2008同时还将vld的头文件include目录路径.vld的库文件lib目录设置好了,简直太贴心.vld下载地址:http://vld.codeplex.com/ (2)在待检测的工程中添加头文件#include "vld.h"(我添加在

自己实现简易的内存泄露检测工具VLD

有一个很著名的内存泄露检测工具Visual leak detected想必大家都不陌生,但今天我们可以自己写一个简易版的.哈哈,自己动手,丰衣足食有木有!!! 它的原理就是我们重载了操作符new和delete,当用new开辟空间的时候,就讲这块空间串到我们定义的结构体MEMNode形成的链表中,(这是老师的写法,在main程序结束时,用check_vld()函数检测有没有内存泄露)但我觉得,如果我们动态开辟了一个对象,在它的析构函数里用delete释放的话,这种方法就不太可行.因为析构函数只有到

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

概述 内存泄漏(memory leak)指由于疏忽或错误造成程序未能释放已经不再使用的内存的情况,在大型的.复杂的应用程序中,内存泄漏是常见的问题.当以前分配的一片内存不再需要使用或无法访问时,但是却并没有释放它,这时就出现了内存泄漏.尽管优秀的编程实践可以确保最少的泄漏,但是根据经验,当使用大量的函数对相同的内存块进行处理时,很可能会出现内存泄漏. 内存泄露可以分为以下几类:1. 常发性内存泄漏.发生内存泄漏的代码会被多次执行到,每次被执行的时候都会导致一块内存泄漏.2. 偶发性内存泄漏.发生

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

初识Visual Leak Detector 灵活自由是C/C++语言的一大特色,而这也为C/C++程序员出了一个难题.当程序越来越复 杂时,内存的管理也会变得越加复杂,稍有不慎就会出现内存问题.内存泄漏是最常见的内存问题之一.内存泄漏如果不是很严重,在短时间内对程序不会有太大的 影响,这也使得内存泄漏问题有很强的隐蔽性,不容易被发现.然而不管内存泄漏多么轻微,当程序长时间运行时,其破坏力是惊人的,从性能下降到内存耗尽,甚 至会影响到其他程序的正常运行.另外内存问题的一个共同特点是,内存问题本身