【转】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
来个测试工程:
- #include <iostream>
- #include "string"
- #include "vector"
- using namespace std;
- int main()
- {
- {
- char *str;
- str = new char[100 + 1];
- strcpy(str, "zengraoli");
- cout << str << endl;
- }
- _CrtDumpMemoryLeaks(); // 内存泄露检测
- return 0;
- }
Ctrl+F5后,在Dbgview.exe中出现了下面的信息:
Detected memory leaks
这个是提示
上面的测试不方便的地方:
但在这上面显然有不太好的地方,比如我需要知道哪一行导致的内存泄露,所以参考csdn blog的一篇文章:http://blog.csdn.net/iuhsihsow/article/details/8492363
再次修改:
- #include "stdafx.h"
- #include <iostream>
- #include "string"
- #include "vector"
- using namespace std;
- #ifdef _DEBUG
- #define _CRTDBG_MAP_ALLOC
- #include <stdlib.h>
- #include <crtdbg.h>
- #define newEx new(_NORMAL_BLOCK, __FILE__, __LINE__)
- #endif
- inline void EnableMemLeakCheck()
- {
- _CrtSetDbgFlag(_CrtSetDbgFlag(_CRTDBG_REPORT_FLAG) | _CRTDBG_LEAK_CHECK_DF);
- }
- int _tmain(int argc, _TCHAR* argv[])
- {
- EnableMemLeakCheck();
- char *str = newEx char[9 + 1];
- cout << str << endl;
- return 0;
- }
Ctrl+F5后,在Dbgview.exe中出现了下面的信息:
可以看到正是25行的地方导致内存泄露的
二、不使用Dbgview.exe,直接使用class
参考文章:http://www.cnblogs.com/FCoding/archive/2012/07/04/2576877.html
Code没来得及细看,能用就是了^_^,方便就行,枉自猜测一下原理----------重载了new和delete,对他俩进行一个计数,并记下行数,两个不为偶数,则就是代表已经出现内存泄露了
MemCheck.h:
- #ifndef MEMCHECK_H
- #define MEMCHECK_H
- #include <cstddef> // for size_t
- // Hijack the new operator (both scalar and array versions)
- void* operator new(std::size_t, const char*, long);
- void* operator new[](std::size_t, const char*, long);
- #define new new (__FILE__, __LINE__)
- extern bool traceFlag;
- #define TRACE_ON() traceFlag = true
- #define TRACE_OFF() traceFlag = false
- extern bool activeFlag;
- #define MEM_ON() activeFlag = true
- #define MEM_OFF() activeFlag = false
- #endif
MemCheck.cpp:
- #include <cstdio>
- #include <cstdlib>
- #include <cassert>
- using namespace std;
- #undef new
- // Global flags set by macros in MemCheck.h
- bool traceFlag = true;
- bool activeFlag = false;
- namespace
- {
- // Memory map entry type
- struct Info
- {
- void* ptr;
- const char* file;
- long line;
- };
- // Memory map data
- const size_t MAXPTRS = 10000u;
- Info memMap[MAXPTRS];
- size_t nptrs = 0;
- // Searches the map for an address
- int findPtr(void* p)
- {
- for (int i = 0; i < nptrs; ++i)
- {
- if (memMap[i].ptr == p)
- {
- return i;
- }
- }
- return -1;
- }
- void delPtr(void* p)
- {
- int pos = findPtr(p);
- assert(p >= 0);
- // Remove pointer from map
- for (size_t i = pos; i < nptrs-1; ++i)
- {
- memMap[i] = memMap[i+1];
- }
- --nptrs;
- }
- // Dummy type for static destructor
- struct Sentinel
- {
- ~Sentinel()
- {
- if (nptrs > 0)
- {
- printf("Leaked memory at:\n");
- for (size_t i = 0; i < nptrs; ++i)
- {
- printf("\t%p (file: %s, line %ld)\n",
- memMap[i].ptr, memMap[i].file, memMap[i].line);
- }
- }
- else
- {
- printf("No user memory leaks!\n");
- }
- }
- };
- // Static dummy object
- Sentinel s;
- } // End anonymous namespace
- // Overload scalar new
- void* operator new(size_t siz, const char* file,
- long line)
- {
- void* p = malloc(siz);
- if (activeFlag)
- {
- if (nptrs == MAXPTRS)
- {
- printf("memory map too small (increase MAXPTRS)\n");
- exit(1);
- }
- memMap[nptrs].ptr = p;
- memMap[nptrs].file = file;
- memMap[nptrs].line = line;
- ++nptrs;
- }
- if (traceFlag)
- {
- printf("Allocated %u bytes at address %p ", siz, p);
- printf("(file: %s, line: %ld)\n", file, line);
- }
- return p;
- }
- // Overload array new
- void* operator new[](size_t siz, const char* file,
- long line)
- {
- return operator new(siz, file, line);
- }
- // Override scalar delete
- void operator delete(void* p)
- {
- if (findPtr(p) >= 0)
- {
- free(p);
- assert(nptrs > 0);
- delPtr(p);
- if (traceFlag)
- {
- printf("Deleted memory at address %p\n", p);
- }
- }
- else if (!p && activeFlag)
- {
- printf("Attempt to delete unknown pointer: %p\n", p);
- }
- }
- // Override array delete
- void operator delete[](void* p)
- {
- operator delete(p);
- }
那哥们的测试工程,挺不错的,有3种情况:
- #include "stdafx.h"
- #include <iostream>
- #include <vector>
- #include <cstring>
- #include "MemCheck.h" // Must appear last!
- using namespace std;
- void Test()
- {
- int *i = new int(0);
- }
- class MyClass
- {
- private:
- int *p;
- public:
- MyClass()
- {
- if(p != NULL)
- {
- p = new int(0);
- }
- }
- ~MyClass()
- {
- if(p != NULL)
- {
- delete p;
- p = NULL;
- }
- }
- };
- void Test2()
- {
- int *i = NULL; // better for read
- i = new int(0);
- int *&y = i; // pointer's reference
- delete i;
- MyClass *pMyClass = new MyClass();
- std::vector<MyClass*> myClasses;
- myClasses.push_back(new MyClass());
- myClasses.push_back(new MyClass());
- std::vector<void*> myVector;
- myVector.push_back(new MyClass());
- myVector.push_back(new MyClass());
- delete (MyClass *)(myVector.at(0));
- delete myVector.at(1); // memory leak
- }
- class Foo
- {
- char* s;
- public:
- Foo(const char*s )
- {
- this->s = new char[strlen(s) + 1];
- strcpy(this->s, s);
- }
- ~Foo()
- {
- delete [] s;
- }
- };
- void Test3()
- {
- cout << "hello\n";
- int* p = new int;
- delete p;
- int* q = new int[3];
- delete [] q;
- /**//*delete r;*/
- vector<int> v;
- v.push_back(1);
- Foo s("goodbye");
- }
- int main()
- {
- TRACE_OFF();
- MEM_ON();
- Test();
- Test2();
- Test3();
- MEM_OFF();
- }
在我编译的时候,会出现一下提示:
运行的时候出现:
对这个cpp的使用说明:
1、使用时在工程中加入在MemCheck.h,而且这个.h文件应该放在所以头文件的后边,因为里面有这么一句代码:#undef new
2、用MEM_ON()和MEM_OFF()来打开和关闭检测
3、TRACE_ON()和TRACE_OFF()用来打开或关闭检测结果的输出(上面的测试代码中使用没做检测结果的输出)
4、可以检测代码中使用了流、标准容器,以及某个类的构造函数分配了空间
【转】c++内存泄露检测,长文慎入!的更多相关文章
- memwatch内存泄露检测工具
工具介绍 官网 http://www.linkdata.se/sourcecode/memwatch/ 其功能如下官网介绍,挑选重点整理: 1. 号称功能: 内存泄露检测 (检测未释放内存, 即 动态 ...
- Visual C++内存泄露检测—VLD工具使用说明[转]
Visual C++内存泄露检测—VLD工具使用说明 一. VLD工具概述 Visual Leak Detector(VLD)是一款用于Visual C++的免费的内存泄露检测工具.他的 ...
- Visual C++内存泄露检测—VLD工具使用说明
一. VLD工具概述 Visual Leak Detector(VLD)是一款用于Visual C++的免费的内存泄露检测工具.他的特点有:可以得到内存泄漏点的调用堆栈,如果可以的话,还 ...
- vld(Visual Leak Detector) 内存泄露检测工具
初识Visual Leak Detector 灵活自由是C/C++语言的一大特色,而这也为C/C++程序员出了一个难题.当程序越来越复 杂时,内存的管理也会变得越加复杂,稍有不慎就会出现内存问题.内存 ...
- Android内存泄露---检测工具篇
内存使用是程序开发无法回避的一个问题.如果我们毫不在意肆意使用,总有一天会为此还账,且痛不欲生...所以应当防患于未然,把内存使用细化到平时的每一行代码中. 内存使用概念较大,本篇先讲对已有app如何 ...
- 【YFMemoryLeakDetector】人人都能理解的 iOS 内存泄露检测工具类
背景 即使到今天,iOS 应用的内存泄露检测,仍然是一个很重要的主题.我在一年前,项目中随手写过一个简单的工具类,当时的确解决了大问题.视图和控制器相关的内存泄露,几乎都不存在了.后来想着一直就那个工 ...
- vld,Bounds Checker,memwatch,mtrace,valgrind,debug_new几种内存泄露检测工具的比较,Valgrind Cheatsheet
概述 内存泄漏(memory leak)指由于疏忽或错误造成程序未能释放已经不再使用的内存的情况,在大型的.复杂的应用程序中,内存泄漏是常见的问题.当以前分配的一片内存不再需要使用或无法访问时,但是却 ...
- C++Builder 内存泄露检测
C++Builder 内存泄露检测 CodeGuard http://bbs.2cto.com/read.php?tid=179933 XE新版里 ReportMemoryLeaksOnShutdow ...
- C/C++内存泄露检测
以下测试基于的gcc版本: gcc (Ubuntu 4.8.4-2ubuntu1~14.04) 4.8.4Copyright (C) 2013 Free Software Foundation, In ...
随机推荐
- jquery 父页面 子页面 同级页面 调用
项目中用到 代码 ,先 展示 ,以便以后用到,直接看下就会明白. var li_divs = parent.$("#servicelist")[0].contentWindow. ...
- .net 对称加密DESCryptoServiceProvider
1.生成密钥以加密和解密数据 DESCryptoServiceProvider 基于一种对称加密算法.对称加密需要密钥和初始化矢量 (IV) 来加密数据.要解密该数据,您必须拥有此同一密钥和 IV.您 ...
- time wait duo
linux 下Time_wait过多问题解决 分类: linux FAQ2011-07-14 11:20 3485人阅读 评论(0) 收藏 举报 linux服务器tcp通讯活动ssh 问题起因: 自己 ...
- ***redis linux 命令使用总结
redis命令参考: http://redisdoc.com/ 1. [root@iZ25rloipcsZ src]# redis-cli-bash: redis-cli: command not f ...
- [2-sat]HDOJ3622 Bomb Game
题意:给n对炸弹,每对炸弹选其中一个爆炸. 每个炸弹爆炸的半径相同 圆不能相交, 求最大半径 2-sat简介 二分半径, 枚举n*2个炸弹 若i炸弹与j炸弹的距离小于半径*2 则建边 比如 第一对炸 ...
- Ubuntu 14.04 + Linux 3.14.34 系统调用实现文件拷贝
采用 64位系统, ubuntu 14.04 + 新内核linux-3.14.34 下载地址https://www.kernel.org/pub/linux/kernel/v3.x/linux-3.1 ...
- 【mysql的编程专题】触发器
类似tp里面的数据模型回调接口,在数据表增删改的前或后触发执行其他的预订的sql; 一个触发器要具备4要素: 1.监视地点 -- 要执行触发器的表 2.监视事件 -- 由什么DML事件来牵引 3.触发 ...
- java:继承
一.继承: java只支持单继承,一个子类只能继承一个父类,使用继承是为了减少类的重复代码,且父类的构造函数不能被子类继承. 当两个类里面有相同的属性或方法,就应该考虑使用继承解决重复代码了. 继承的 ...
- java中文排序
对中文名称进行排序,不多说,上代码 package test; /** * @Title: Person.java * @Copyright: Copyright (c) 2012-11-19 * @ ...
- Java API —— 反射
1.类加载器 1)类的加载 · 当程序要使用某个类时,如果该类还未被加载到内存中,则系统会通过加载,连接,初始化三步来实现对这个类进行初始化. · 加载 :就是 ...