【转】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 ...
随机推荐
- hibernate 多对多
HibernateHibernate多对多关联映射通常别拆分成两个多对一关联映射1. 下面的HostBean.UserBean.UserHostBean,UserHostBean是两个表之间的关联表, ...
- POJ 2771 Guardian of Decency(求最大点独立集)
该题反过来想:将所有可能发生恋爱关系的男女配对,那么可以带出去的人数应该等于这个二分图的最大独立集 先要做一下预处理,把不符合要求的双方先求出来, company[i][j]表示i.j四个标准都不符合 ...
- 2014多校第一场A题 || HDU 4861 Couple doubi
题目链接 题意 : 有K个球,给你一个数P,可以求出K个值,(i=1,2,...,k) : 1^i+2^i+...+(p-1)^i (mod p).然后女朋友先取,再xp取,都希望赢,如果女朋友能赢输 ...
- 深入理解JVM—Java 6 JVM参数配置说明
原文地址:http://yhjhappy234.blog.163.com/blog/static/316328322011119111014657/ 使用说明< xmlnamespace pre ...
- cojs 自己出的题目 解题报告
省选成功成为河北B队队长QAQ 真是忧桑 所以在cojs上出了一套鬼畜的关于树的套题 黑白树: 我们先不考虑R操作 设x是u的祖先,那么fa(x)的贡献显然是 fa(x)*(sz(fa(x))-sz( ...
- lintcode:两个数的和
题目 两数之和 给一个整数数组,找到两个数使得他们的和等于一个给定的数target. 你需要实现的函数twoSum需要返回这两个数的下标, 并且第一个下标小于第二个下标.注意这里下标的范围是1到n,不 ...
- Visual StudioTools for Unity 使用技巧2
在之前的博客介绍了 Visual Studio Tools for Unity的安装和使用. http://www.cnblogs.com/petto/p/3886811.html 其实这个工具还提供 ...
- C++Builder和VC的比较
C++Builder和VC的比较 其实很久以前我就想写这篇文章,其原因一方面是因为笔者深深感觉到C++ Builder的确是一个先进与强大的程式开发工具,但更最重要的一点是,我深信C++ Builde ...
- Android 动态改变布局属性RelativeLayout.LayoutParams.addRule()
我们知道,在 RelativeLayout 布局中有很多特殊的属性,通常在载入布局之前,在相关的xml文件中进行静态设置即可. 但是,在有些情况下,我们需要动态设置布局的属性,在不同的条件下设置不同的 ...
- java类的加载以及初始化顺序
类的加载和初始化的了解对于我们对编程的理解有很大帮助,最近在看类的记载方面的问题.从网上查阅了若干文章,现总结如下: 我们通过一段代码来了解类加载和初始化的顺序: package com.classl ...