【转】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 ...
随机推荐
- 【WCF--初入江湖】11 安全
11 安全 前言 [1]传输安全 传输安全模式 传输安全与绑定协议 [2]身份验证 身份验证分类 证书 示例:传输安全匿名客户端证书的使用 1. 传输安全 保证信息在传输过程中的 ...
- tomcat 解析(三)-启动框架
TOMCAT源码分析(启动框架)前言: 本文是我阅读了TOMCAT源码后的一些心得. 主要是讲解TOMCAT的系统框架, 以及启动流程.若有错漏之处,敬请批评指教!建议: 毕竟TOMCAT的框 ...
- 【mongoDB中级篇②】索引与expain
索引的操作 数据库百分之八十的工作基本上都是查询,而索引能帮我们更快的查询到想要的数据.但是其降低了数据的写入速度,所以要权衡常用的查询字段,不必在太多字段上建立索引. 在mongoDB中默认是用bt ...
- 缓存初解(四)---Ibatis的缓存配置+Ehcache
项目完结,整理一些技术方面的相关收获. 已经记不得EhCacheController这个实现类最早来自于那里了,总之稍加修改后非常有效果,大家就这么用了,感谢最初开源的那位兄弟.这里,主要是做个记录, ...
- avi 格式详解
http://blog.csdn.net/becomly/article/details/6283004 http://blog.csdn.net/easecom/article/details/45 ...
- login.java
import java.awt.*; import javax.swing.*; import java.awt.event.*; public class Login extends JFrame ...
- Photoshop:笔刷制作和安装
笔刷制作 1.新建一个文档,大小为要制作的笔刷大小,把画笔图像放里面 2.选择:菜单->编辑->定义画笔预设,这时在画笔面板中会出现刚定义的画笔 3.存储画笔,可以把当前的笔刷保存为一个. ...
- java:访问权限
访问权限四大类:权限从大->小 1.public: 公共权限 2.protected: 受保护权限 3.default: 包级别访问权限/默认权限 4.private: 私有权限 以p ...
- HDU5093——Battle ships(最大二分匹配)(2014上海邀请赛重现)
Battle ships Problem DescriptionDear contestant, now you are an excellent navy commander, who is res ...
- Android 拦截短信
public class SMSMess extends BroadcastReceiver { @Override public void onReceive(Context arg0, Inten ...