Windows平台上C++开发内存泄漏检查方法
充分的利用调试工具可以非常方便地避免内存泄漏问题。
这里介绍两种方法,互为补充,第一种是VC编译器提供的方法,第二种是专用的内存泄漏检查工具Memmory Validator。这两种方法的基本原理是一样的:内存分配要通过CRT在运行时实现,只要在分配内存和释放内存时分别做好记录,程序结束时对比分配内存和释放内存的记录就可以确定是不是有内存泄漏。其中,第一种方法重载了new操作符,第二种方法是替换了CRT运行时库,在用户程序与运行库之间加了一层,用于记录内存分配情况。两种方法的不同是前者是在编译时完成的,分析内存情况的代码编译到执行文件中,用于程序的debug版本,后一种对编译过程没有影响,在执行过程中截留与CRT的交互信息。
第一种方法是MSDN中介绍了,在需要检查内存分配情况的cpp文件中引用<stdlib.h>和<ctrdbg.h>两个头文件,放于最头部,再用宏代换的方法用重载后的new操作符代替原来的new操作符,如下列代码所示,在程序退出的位置调用_CrtDumpMemoryLeaks()输出全部没有释放的内存内容,及申请这些内存的源代码位置,非常便于调试。
但这种方法有缺陷,_CrtDumpMemoryLeaks()必须在main()函数结束之前调用,所以main()函数中的栈对象还没有析构,会被当做内存泄漏,如下面代码中的NewClass类的对象,实际是没有问题的。另外就是不同编译器实现非ASCII码字符时可能会有所不同,如下面代码中的汉字串都被视为内存泄漏。
#include <stdlib.h>
#include <crtdbg.h>
#include <string>
#include <iostream>
#include <vector>
using namespace std;
#define DEBUG_NEW new(_NORMAL_BLOCK, __FILE__, __LINE__)
#define new DEBUG_NEW
struct AlertDescriptionString
{
unsigned int ID;
string Name;
string Desp;
};
const AlertDescriptionString String[] =
{
{0,"AAA","BBBB"},
// memory leak count by _CRTDBG_MAP_ALLOC
{1,"CCC","__XXX__检测到可能由AirJack发出的数据包"}
};
struct AlertDescriptionStr
{
unsigned int ID;
char* Name;
char* Desp;
};
const AlertDescriptionStr Str[] =
{
{0,"AAA","BBBB"},
{1,"CCC","检测到可能由AirJack发出的数据包"}
};
void leak_memory(void)
{
vector<unsigned int *> vec;
for( int j = 0; j < 2; j++)
{
vec.push_back(new unsigned int(0));
}
}
class NewClass
{
void * p ;
public:
NewClass()
{
p = (void*) new char[10];
}
~NewClass()
{
delete [] p;
}
};
int * p = new int(9);
int real_main_fun (int argc, char ** argv)
{
leak_memory();
return 0;
}
int main (int argc, char ** argv)
{
string str("__YYY__检测到可能由AirJack发出的数据包");
NewClass cls;
int i = real_main_fun(argc, argv); // 原有的main函数体
if(_CrtDumpMemoryLeaks())
cout<< " memory leak " << endl;
return i;
}
第二种方法正好是它的补充,Memmory Validator可以检查程序整个运行过程中的内存分配情况,也可以将内存泄漏的位置显示出来,如图所示。

在实际应用第一种方法时,可以采用两个头文件,用于大型工程的调试,几乎不对其他部分代码产生影响。
-----------------------------------------------------------------------------
//config.h
#define MEMORY_DEBUG
#ifdef MEMORY_DEBUG
#include <stdlib.h>
#include <crtdbg.h>
#endif // MEMORY_DEBUG
------------------------------------------------------------------------------
//debug.h
#ifdef MEMORY_DEBUG
#define DEBUG_NEW new(_NORMAL_BLOCK, __FILE__, __LINE__)
#define new DEBUG_NEW
#endif // MEMORY_DEBUG
-------------------------------------------------------------------------------
//main.cpp
#include "config.h” // config.h, 第一个头文件
#include "alertparser.h"
#include "alertinfocache.h"
#include <iostream>
#include <pcap.h>
#include "debug.h" //debug.h, 最后一个头文件
int main (int argc, char ** argv)
{
int i = real_main_fun(argc, argv); // 原有的main函数体
if(_CrtDumpMemoryLeaks())
cout<< " memory leak " << endl;
return i;
}
Windows平台上C++开发内存泄漏检查方法的更多相关文章
- C++程序在Windows平台上各种定位内存泄漏的方法,并对比了它们的优缺点
一.前言 在Linux平台上有valgrind可以非常方便的帮助我们定位内存泄漏,因为Linux在开发领域的使用场景大多是跑服务器,再加上它的开源属性,相对而言,处理问题容易形成“统一”的标准.而在W ...
- c# 内存泄漏检查心得
系统环境 windows 7 x64 检查工具:ANTS Memory Profiler 7 或者 .NET Memory Profiler 4.0 开发的软件为winform / windows s ...
- Windows平台下PHP开发环境的配置
Windows平台下PHP开发环境的配置 一.基本环境 1.Windows XP 32位 2.Apache 2.2.25,下载地址:http://mirror.bit.edu.cn/apache/ht ...
- iOS学习——内存泄漏检查及原因分析
项目的代码很多,前两天老大突然跟我说项目中某一个ViewController的dealloc()方法没有被调用,存在内存泄漏问题,需要排查原因,解决内存泄漏问题.由于刚加入项目组不久,对出问题的模块的 ...
- Windows平台上Caffe的训练与学习方法(以数据库CIFAR-10为例)
Windows平台上Caffe的训练与学习方法(以数据库CIFAR-10为例) 在完成winodws平台上的caffe环境的搭建之后,亟待掌握的就是如何在caffe中进行训练与学习,下面将进行简单的介 ...
- C++程序内存泄漏检测方法
一.前言 在Linux平台上有valgrind可以非常方便的帮助我们定位内存泄漏,因为Linux在开发领域的使用场景大多是跑服务器,再加上它的开源属性,相对而言,处理问题容易形成“统一”的标准.而在W ...
- Android内存管理(5)*官方教程:Logcat内存日志各字段含义,查看当前内存快照,跟踪记录内存分配,用adb查看内存情况时各行列的含义,捕获内存快照的3种方法,如何让程序暴漏内存泄漏的方法
Investigating Your RAM Usage In this document Interpreting Log Messages 内存分析日志中各消息的含 ...
- VS2005内存泄漏检测方法[转载]
一.非MFC程序可以用以下方法检测内存泄露: 1. 程序开始包含如下定义: #ifdef _DEBUG #define DEBUG_CLIENTBLOCK new( _CLIENT_BLOCK, __ ...
- windows平台下的oracle ORA-01031的解决方法
今天下午遇到一个很怪异的问题,在windows平台下sqlplus / as sysdba登陆数据库,提示权限不足, 当时就纳闷了,sys用户登陆数据库还能权限不足,问题出现了,就开始寻找解决方法呗 ...
随机推荐
- c# 中日期的使用
上月第一天:DateTime.Parse(DateTime.Now.AddMonths(-1).ToString("yyyy-MM-01")) 上周星期天:DateTime.Par ...
- 实现iOS项目一款用swift实现的应用top源码
Top 后台 Swift版本Ios 8 / iPhone 5S适配这边有个登陆,如果你们想测试的话,可以用这个账号, 账号:18868879362 密码:420562 源码下载: http://c ...
- 第十篇、Swift -- WebSocket
每当小编再开发中遇到了困难,在网上搜,简直是垃圾堆里找金子.国内网站真的全不可靠,最后FQ去国外网站寻找,才可以找到.找到了写websocket文章,同时找到了集成的框架文件,一个叫Starscrea ...
- Java-IO 输入输出流详解
一.文件的编码 开发时一定要注意项目默认的编码!!!!!!!! 文件操作的时候一定要记得关闭!!!!!!!! ASCII:美国标准 ...
- ◆◆◆◆◆◆◆◆◆◆◆linux下软件包的管理◆◆◆◆◆◆◆◆◆◆◆◆◆◆
查看与制定的路径名相匹配的软件包 [root@localhost certs]# which ls alias ls='ls --color=auto' /bin/ls [root@localhost ...
- UserControl eventhander 注册问题
1. 如果主页面调用UserControl来画界面 2. UserControl局部变化需要通过事件通知主页面,通过UserControl定义EventHandler,主界面注册UserControl ...
- Android:ListView之ViewHolder
前言 在开发Android应用过程中经常要与列表展示打交道,比如Listview.在使用过程中如果不能正确的进行细节处理那么对性能还是有很大的损耗的. Listview展示内容是通过一个Adapter ...
- 分享php中四种webservice实现的简单架构方法及实例[转载]
[转载]http://www.itokit.com/2012/0417/73615.html 本人所了解的webservice有以下几种:PHP本身的SOAP,开源的NUSOAP,商业版的PHPRPC ...
- Node.Js之【Stream 之复制文件问题】
var fs = require('fs'), path = require('path'), out = process.stdout; var filePath = 'F:/IMG_0221.MO ...
- SendMessage 窗口函数
函数功能:该函数将指定的消息发送到一个或多个窗口.此函数为指定的窗口调用窗口程序,直到窗口程序处理完消息再返回.而函数PostMessage不同,将一个消息寄送到一个线程的消息队列后立即返回. MSD ...