本文介绍,当VC++或者MFC程序,出现内存泄露时,如何快速定位的方法,这种方法有一定的局限性,在注意事项中会给出的。

MFC程序

    当MFC程序出现内存泄露时,退出程序时的VS调试输出窗口,一般会有如下显示:

   上面显示了在程序的哪个文件的哪行语句,发生了内存泄露,其中:

   {345}: 表示 内存分配编号

   normal block:表示 内存块类型,有普通块(普通程序分配)、客户端块(分配基于CObject的内存)和CRT块(库函数内部分配)这几种类型

   0x0074A030:以16进制形式输出的内存位置

   40 bytes long: 以字节为单位的内存块大小

   Data<   >CD CD ..:内存块前16个字节的内容,16进制表示。

      定位内存泄露位置,可以双击泄露信息,也可以在输出窗口 按F4键,跳转到 出错行。

 

普通VC++程序

    在普通VC++程序中,要类似MFC中内存检测的效果,需要做如下操作。

    1.  在头文件中,添加  #include <ctrdbg.h>

    2.  在程序入口最开始处,添加 下面两句话即可

        _CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );    //设置调试堆函数跟踪分配的方式
        //_CrtSetBreakAlloc();     //这句话,在确实有内存泄露的情况下,给 内存分配编号

    3. 按F5,运行程序,等待程序退出后,在输出窗口可以看到下面的情况:

     

     如图所示,程序有两处内存泄露地方,分配编号为 476 和 475,此时,给_CrtSetBreakAlloc()函数传入476参数,再次运行程序,在退出时,会弹出如下窗口:

    

点击 中断  跳到,_CrtSetBreakAlloc()中断的地方,然后在程序中,通过查看调用堆栈,就可以看到应用程序的哪一次new操作没有执行delete操作。

在中断的同时,也可以从控制台中,看到整个程序析构的顺序,如下图所示:

 

注意事项

1. 当程序确认没有内存泄露时,不可以调用_CrtSetBreakAlloc(475),因为,这样会在指定内存分配次数发生时,强制中断程序。

2. 这种检测内存分配的方式,要求,程序在执行过程中,是可还原的(多次执行过程的内存分配顺序不会发送变化),这个假设,在多数情况下是成立的,不过,在多线程执行的环境下,有时候难以保证。

3. 对于普通C程序,上述检测方法也是成立的,只不过new换成了malloc,delete换成了free

4. 比如 int *p = new int[4]; delete p; 这种方式的泄露,上述方法是检测不出来,此时,需要cppcheck等更有力的工具来检查。

 

参考链接:C++调试堆

VC++ 内存泄露与检测的一种方法的更多相关文章

  1. CPP-基础:内存泄露及其检测工具

    [转]浅谈C/C++内存泄露及其检测工具   对于一个c/c++程序员来说,内存泄漏是一个常见的也是令人头疼的问题.已经有许多技术被研究出来以应对这个问题,比如 Smart Pointer,Garba ...

  2. [转]浅谈C/C++内存泄露及其检测工具

    转自:http://www.cnblogs.com/taoxu0903/archive/2007/10/27/939261.html 对于一个c/c++程序员来说,内存泄漏是一个常见的也是令人头疼的问 ...

  3. C/C++内存泄露及检测工具

    内存泄漏的定义   一般我们常说的内存泄漏是指堆内存的泄漏.堆内存是指程序从堆中分配的,大小任意的(内存块的大小可以在程序运行期决定),使用完后必须显示释放的内 存.应用程序一般使用malloc,re ...

  4. C++中内存泄露的检测

    C++没有java的内存垃圾回收机制,在程序短的时候可能比较容易发现问题,在程序长的时候是否有什么检测的方法呢? 假设有一个函数可以某点检测程序的内存使用情况,那是否可以在程序开始的时候设置一个点,在 ...

  5. Windows系统中内存泄露与检测工具及方法

    1.检测需要使用的工具:windbg工具.检测前,需要先安装windbg工具.安装了该工具后,会在安装目录下有一个umdh工具.假设windbg安装在以下目录下:D:\Program Files\De ...

  6. Android内存泄露自动检测神器LeakCanary

    经典的面试题: a.怎样在coding过程中避免内存泄露? b.怎样检测内存泄露? 这两个问题我想大部分Android 职位面试时都会被问到吧. 怎样避免就不赘述了,网上很多答案. 工具呢,当然也有很 ...

  7. c/c++内存泄露的检测方法

    此文内容摘自 https://zhuanlan.zhihu.com/p/22664202 作为   从零开始的 JSON 库教程(三):解析字符串解答篇  的笔记 1A. Windows 下的内存泄漏 ...

  8. jenkins的sonarqube之代码检测的两种方法

    #:sonarqube下载地址,我们安装6.7  高版本已经不支持MySQL和Mariadb(最小3G内存) https://www.sonarqube.org/downloads/ #:安装文档 h ...

  9. VC启动一个新线程的三种方法

    第一种AfxBeginThread() 用AfxBeginThread()函数来创建一个新线程来执行任务,工作者线程的AfxBeginThread的原型如下: CWinThread* AfxBegin ...

随机推荐

  1. Web程序中的懒加载异常说明及解决方案

    所谓懒加载(lazy)就是延时加载,延迟加载. 什么时候用懒加载呢,我只能回答要用懒加载的时候就用懒加载. 至于为什么要用懒加载呢,就是当我们要访问的数据量过大时,明显用缓存不太合适, 因为内存容量有 ...

  2. linux下修改tomcat使用的jdk版本

    遇到一种情况,就是linux上好像掉文件了,JDK的目录下没有了,具体问题还不清楚,不过要赶紧修复,不能影响其他程序的运行. 结构重新安装了JDK,tomcat还是启动失败,看l启动日志发现没找到还是 ...

  3. centos7 安装oracle jdk 与openjdk 实现切换

    1. 分别安装oraclejdk 与openjdk #下载安装oraclejdk rpm -ivh --prefix=/usr.java/java1.8 ***.rpm #安装openjdk su - ...

  4. 火狐FireFox恢复备份失败,无法处理备份文件

    问题:火狐浏览器丢失书签后尝试恢复书签,按[Ctrl + Shift + B]弹出我的足迹,选择[导入和备份]-->[恢复]中任一文件,弹窗[无法处理备份文件]. 解决办法: 先找到并打开火狐浏 ...

  5. cocos2d-Lua02Lua面向对象

    1 Lua中的面向对象 1.1 问题 lua不是一个面向对象的语言.可是他又有面向对象的思想. lua中的面向对象是伪面向对象.伪面向对象就要用到table实现. 由table模拟了一个面向对象的编程 ...

  6. 【jquery】图片前后对比效果——beforeAfter

    今天分享一款 jquery 插件——图片前后对比(beforeAfter),效果如下: 使用方法: <!DOCTYPE HTML> <html lang="en" ...

  7. PHP开发工程师-技能树

    参考进阶-PHP程序员的技术成长规划-http://blog.csdn.net/heiyeshuwu/article/details/40098043 LNMP / LAMP 环境搭建(单组件安装,非 ...

  8. 使用JAAS登录kerberos服务器

    java代码: package com.snsprj.jaas0822; import javax.security.auth.*; import javax.security.auth.callba ...

  9. github fork 同步

    git remote -v git remote add upstream url git fetch upstream git checkout master git merge upstream/ ...

  10. linux,chmod如何更改所有子目录的权限,要包括隐藏文件

    for file in `find . -print` do chmod 777 -R $file done