原文网址: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. PE工具

    PE编辑工具 Stud_PE v. 2.4.0.1 PE工具,用来学习PE格式十分方便. http://www.cgsoftlabs.ro/ 汉化版:http://bbs.pediy.com/show ...

  2. Unity3d - 初学篇 Event Functions 的 继承 机制

    我们知道Start() Update() 等之类的 事件函数 在Unity 主线程中是依次调用的.至于调用的顺序可以查手册. 由此继承机制也会发生一些改变. 测试一: public class MyT ...

  3. 从后端到页面:如何全方位监控 Ruby 应用?

    [编者按]本文参考技术分享 ,由 OneAPM 工程师补充整理,并且已经征得原作者的同意. 为什么选择 OneAPM ? 在性能监控领域,业界比较有名的是 New Relic 还有 Appdynami ...

  4. hdu 1757 A Simple Math Problem (矩阵快速幂,简单)

    题目 也是和LightOJ 1096 和LightOJ 1065 差不多的简单题目. #include<stdio.h> #include<string.h> #include ...

  5. Linux防火墙(Iptables)的开启与关闭

    Linux防火墙(iptables)的开启与关闭 Linux中的防火墙主要是对iptables的设置和管理. 1. Linux防火墙(Iptables)重启系统生效 开启: chkconfig ipt ...

  6. 读写txt文件

    public void SetUpdateTime(string strNewDate) { try { var path =Application.StartupPath + Configurati ...

  7. linux入门教程(二) 图形界面还是命令窗口

    对于linux的应用,我想大多数都是用在服务器领域,对于服务器来讲真的没有必要跑一个图形界面.所以我们平时安装linux操作系统时往往是不安装图形界面的.说到这里也许你会有疑问,图形界面还能选择装或者 ...

  8. Android中使用HTTP和HttpClient进行通信

    /** * 使用HTTP的Get方式进行数据请求 */ protected void httpGet() { /** * 进行异步请求 */ new AsyncTask<String, Void ...

  9. java使用Apache POI操作excel文件

    官方介绍 HSSF is the POI Project's pure Java implementation of the Excel '97(-2007) file format. XSSF is ...

  10. 与Google轻轻地擦肩而过

    第一集 因为那几年三天两头往硅谷里飞,所以我实在记不清这个故事到底是发生在98年还是99年夏天某日的一个下午. 那天我和Excite.com的创始人Mark V. H.在Palo Alto的一家餐厅共 ...