【转】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 ...
随机推荐
- 【面试题003】c数组做为参数退化的问题,二维数组中的查找
[面试题003]c数组做为参数退化的问题,二维数组中的查找 一,c数组做为参数退化的问题 1.c/c++没有记录数组的大小,因此用指针访问数组中的元素的时候,我们要确保没有超过数组的边界, 通过下面 ...
- Chp14: Java
1.finally keyword: finally keyword is used in association with a try/catch block and guarantees that ...
- crontab 不能执行git命令问题备忘
这问题够隐蔽,折腾了近两个小时. 命令 git checkout tagname 手工执行都正常 但在crontab运行时发现分支一直切不过去. 后来告诉是crontab默认的 path 设置和系统 ...
- Perl 三种时间time,localtime,gmttime
#!/usr/bin/perl use warnings; use diagnostics; use strict; use POSIX; print "time: ", time ...
- PKUSC 模拟赛 day2 下午总结
终于考完了,下午身体状况很不好,看来要锻炼身体了,不然以后ACM没准比赛到一半我就挂掉了 下午差点AK,有一道很简单的题我看错题面了所以没有A掉 第一题显然是非常丝薄的题目 我们很容易通过DP来O(n ...
- 李洪强iOS开发支付集成之微信支付
iOS开发支付集成之微信支付 微信支付也是需要签名的,也跟支付宝一样,可以在客户端签名,也可以在后台签名(当然,为了安全还是推荐在服务器上做签名,逻辑也比较好理解). 1 - 集成前首先要看看文档 开 ...
- React 性能调优原理
一.React影响性能的两个地方 二.调优原理
- MyEclipse 2013 开发WebService
1.在Package Explorer窗口右键File新建WebService Project项目,我的名称为:TestWebService 2.WebService Framework选择JAX-W ...
- 转Unity 异常操作
摘要 使用 unity 处理异常的方法可能会与你的直觉不符.本文将给出正确的处理方法,并简单剖析Unity这部分源代码. 处理异常 打算用Unity的AOP截获未处理的异常,然后写个日志什么的,于是我 ...
- 设计模式之Inheritance versus Parameterized Types 继承和参数化类型
Another (not strictly object-oriented)technique for reusing functionality is through parameterized t ...