【转】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 ...
随机推荐
- hdu 4869
一个机智题,可惜比赛的时候没有机智出来 #include<cstdio> #include<cstring> #include<cmath> #include< ...
- uva 11375
思路是刘书上的 但是个高精度 java 大数 ~~ import java.util.*; import java.io.*; import java.math.BigInteger; public ...
- crud springmvc
实体类:Student.java package demo.entity; public class Student { private int id; private String name; pr ...
- tomcat 解析(二)-消息处理过程
接下来我们应该去了解一下 tomcat 是如何处理jsp和servlet请求的. 1. 我们以一个具体的例子,来跟踪TOMCAT, 看看它是如何把Request一层一层地递交给下一个容器, 并最后交 ...
- 利用Qemu Guest Agent (Qemu-ga) 实现 Openstack 监控平台
经常使用vmWare的同学都知道有vmware-tools这个工具,这个安装在vm内部的工具,可以实现宿主机与虚拟机的通讯,大大增强了虚拟机的性能与功能, 如vmware现在的Unity mode下可 ...
- Strange java.lang.ArrayIndexOutOfBoundsException thrown on jetty startup
http://stackoverflow.com/questions/26496338/strange-java-lang-arrayindexoutofboundsexception-thrown- ...
- 桥接模式(Bridge Pattern)
1,定义 桥接模式(Bridge Pattern),也称为桥梁模式,其用意是将抽象化与实现化脱耦,使得两者可以独立的变化,它可以使软件系统沿着多个方向进行变化,而又不引入额外的复杂 ...
- 2010年山东省第一届ACM大学生程序设计竞赛 Balloons (BFS)
题意 : 找联通块的个数,Saya定义两个相连是 |xa-xb| + |ya-yb| ≤ 1 ,但是Kudo定义的相连是 |xa-xb|≤1 并且 |ya-yb|≤1.输出按照两种方式数的联通块的各数 ...
- Oracle 6 - 锁和闩 - 锁类型
Oracle锁大类 1.DML锁 (SELECT, INSERT, UPDATE, DELETE, MERGE是对数据库加的锁, 可能是行锁,也可能是表锁) 2.DDL锁 (Create, Alter ...
- cygwin如何断点续传
对于Cygwin,如果想安装的东西比较多的话,推荐先选择“Download without installing”,下载完了再从本地安装. 好了,说关于断点续传.我所知道的是—— 网上有说法:下载失败 ...