原文网址: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. hibernate 多对多

    HibernateHibernate多对多关联映射通常别拆分成两个多对一关联映射1. 下面的HostBean.UserBean.UserHostBean,UserHostBean是两个表之间的关联表, ...

  2. POJ 2771 Guardian of Decency(求最大点独立集)

    该题反过来想:将所有可能发生恋爱关系的男女配对,那么可以带出去的人数应该等于这个二分图的最大独立集 先要做一下预处理,把不符合要求的双方先求出来, company[i][j]表示i.j四个标准都不符合 ...

  3. 2014多校第一场A题 || HDU 4861 Couple doubi

    题目链接 题意 : 有K个球,给你一个数P,可以求出K个值,(i=1,2,...,k) : 1^i+2^i+...+(p-1)^i (mod p).然后女朋友先取,再xp取,都希望赢,如果女朋友能赢输 ...

  4. 深入理解JVM—Java 6 JVM参数配置说明

    原文地址:http://yhjhappy234.blog.163.com/blog/static/316328322011119111014657/ 使用说明< xmlnamespace pre ...

  5. cojs 自己出的题目 解题报告

    省选成功成为河北B队队长QAQ 真是忧桑 所以在cojs上出了一套鬼畜的关于树的套题 黑白树: 我们先不考虑R操作 设x是u的祖先,那么fa(x)的贡献显然是 fa(x)*(sz(fa(x))-sz( ...

  6. lintcode:两个数的和

    题目 两数之和 给一个整数数组,找到两个数使得他们的和等于一个给定的数target. 你需要实现的函数twoSum需要返回这两个数的下标, 并且第一个下标小于第二个下标.注意这里下标的范围是1到n,不 ...

  7. Visual StudioTools for Unity 使用技巧2

    在之前的博客介绍了 Visual Studio Tools for Unity的安装和使用. http://www.cnblogs.com/petto/p/3886811.html 其实这个工具还提供 ...

  8. C++Builder和VC的比较

    C++Builder和VC的比较 其实很久以前我就想写这篇文章,其原因一方面是因为笔者深深感觉到C++ Builder的确是一个先进与强大的程式开发工具,但更最重要的一点是,我深信C++ Builde ...

  9. Android 动态改变布局属性RelativeLayout.LayoutParams.addRule()

    我们知道,在 RelativeLayout 布局中有很多特殊的属性,通常在载入布局之前,在相关的xml文件中进行静态设置即可. 但是,在有些情况下,我们需要动态设置布局的属性,在不同的条件下设置不同的 ...

  10. java类的加载以及初始化顺序

    类的加载和初始化的了解对于我们对编程的理解有很大帮助,最近在看类的记载方面的问题.从网上查阅了若干文章,现总结如下: 我们通过一段代码来了解类加载和初始化的顺序: package com.classl ...