浅析C/C++内存泄漏的解决办法

原创 2012年03月23日 16:46:28

使用C/C++语言开发的软件在运行时,出现内存泄漏。可以使用以下两种方式,进行检查排除。

⑴ 使用工具软件BoundsChecker,BoundsChecker是一个运行时错误检测工具,它主要定位程序运行时期发生的各种错误。它通过驻留在集成开发环境内部的自动处理调试程序来加速应用程序的开发,缩短产品发布时间。BoundsChecker对于编程中的错误(大多数是C++中特有的)提供了清晰的详细的分析。它能够检测和诊断出,在静态堆栈内存中的错误以及内存和资源泄漏问题。在集成开发环境下,调试运行DEBUG版程序,BoundsChecker在运行时检测内存泄漏,并在可能出现内存泄漏的代码处中断程序运行,开发人员可根据调用现场状态,排除内存泄漏。

⑵ 调试运行DEBUG版程序,运用以下技术:CRT(C run-time libraries)、运行时函数调用堆栈、内存泄漏时提示的内存分配序号(集成开发环境OUTPUT窗口),综合分析内存泄漏的原因,排除内存泄漏。

首先,需要在程序中包含以下语句,用来启用调试堆函数(注:语句的顺序是固定的)

#define CRTDBG_MAP_ALLOC
#include <stdlib.h>
#include <crtdbg.h>


其次,设置内存泄漏检测报告。使用以下语句,在程序结束后,自动调用_CrtDumpMemoryLeaks方法,在OUTPUT窗口中报告内存泄漏的相关信息

_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);

 

最后,根据OUTPUT窗口中提示的内存泄漏相关信息,排除泄漏。分两种情况。

情况一、比较简单。程序退出时,在OUTPUT窗口中,直接报告:出现内存泄漏的源代码文件名及具体代码行数。只需要分析此处代码,根据上、下文修改,一般就可以正确释放内存了。例如:

Detected memory leaks!

Dumping objects ->

C: \MyProjects\LeakTest\LeakTest.cpp(20): {18} normal block at 0x00780E80, 64 bytes long.

Data: < > CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD

Object dump complete.

C: \MyProjects\LeakTest\LeakTest.cpp(20)

情况二、比较麻烦。错误报告没有映射到源文件。可使用_CrtSetBreakAlloc方法来检查定位内存泄漏位置。

例如: 

Detected memory leaks!

Dumping objects ->

{18} normal block at 0x00780E80, 64 bytes long.

Data: < > CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD

Object dump complete.

注意到报告中的一个信息:{18}。大括号中的这个整数值代表了内存分配顺序号。这个例子中,{18}代表了第18次内存分配操作发生了泄漏。在程序运行时,_CrtSetBreakAlloc方法可以在指定的内存分配次数时中断程序。使用这种方式获得的信息,比在程序退出时获得文件名及行号更有价值。因为报告内存泄漏文件名及行号,获得的只是静态信息,而_CrtSetBreakAlloc则是把整个现场恢复,可以通过对函数调用栈的分析、以及使用其他在线调试技巧,来分析产生内存泄漏的原因。_CrtSetBreakAlloc要求你的程序执行过程是可还原的(即:多次执行过程的内存分配顺序不会发生变化),这个假设在多数情况下成立。不过,在多线程的情况下,这个要求有时难以保证。但是虽然内存分配顺序号是变化的,但是变化的顺序号却总是那几个,也就是说,对某个位置的内存泄漏,多运行几次程序,内存分配的顺序号很可能会重复。所以,多线程环境下,也可以使用_CrtSetBreakAlloc方法来定位内存泄漏。具体操作步骤如下:

①先在调试状态下运行几次程序,观察内存分配顺序号是哪几个值。
②用出现次数最多的那个顺序号来设断点。即:在代码中添加如下调用:_CrtSetBreakAlloc(18);(假设: OUTPUT窗口中,报告{18}最多。即:第18次内存分配出现泄漏的情况较常发生)
③在调试状态下运行程序,在断点停下时,打开"调用堆栈"窗口,找到对应发生内存泄漏的源代码。
④退出程序,观察OUTPUT窗口的内存泄漏报告,看本次内存分配的顺序号是不是和预设值(_CrtSetBreakAlloc中设置的值)相同,如果相同,就找到了;如果不同,就重复步骤3,直到相同。
⑤最后根据分析结果,在适当的位置释放分配的内存。

 

在VS2013平台下如何快速解决c++代码内存泄漏问题

在学习FPS3000人脸关键点定位算法时,发现github上的源码,存在大量的内存泄漏问题,在训练的时发现内存一直在增长,测试的时候也存在内存无法彻底释放的问题。 一直以为是存放模型参数vector结...
  • dyx810601
  • dyx810601
  • 2016年08月02日 14:21
  • 2714

C++内存泄漏和内存碎片的产生及避免策略

1.内存泄漏的定义      一般我们常说的内存泄漏是指堆内存的泄漏。堆内存是指程序从堆中分配的,大小任意的(内存块的大小可以在程序运行期决定),使用完后必须显示释放的内存。应用程序一般使用mal...
  • u010893129
  • u010893129
  • 2015年02月18日 11:05
  • 5425

内存泄漏以及常见的解决方法

之所以撰写这篇文章是因为前段时间花费了很大的精力在已经成熟的代码上再去处理memory leak问题。写此的目的是希望我们应该养成良好的编码习惯,尽可能的避免这样的问题,因为当你对着一大片的代码再去处...
  • quzhongxin
  • quzhongxin
  • 2015年05月07日 10:05
  • 1403

Android mvp简单模型搭建及其防内存泄漏解决办法

  • 2017年03月15日 17:23
  • 6.68MB
  • 下载

PHP使用多进程解决办法处理大数据/内存泄漏

最近在写一个数据分析系统(亿级数据),由于循环从数据库读取数据库,数据处理量较大,会造成进程崩掉。后来想到了使用多进程的办法来解决,使用循环创建多个子进程的方式来分布到各个采集节点上,再着要先修改下P...
  • liangpz521
  • liangpz521
  • 2013年05月03日 17:40
  • 1366

Android程序内存泄漏的原因和解决办法

内存泄漏也称作“存储渗漏”,用动态存储分配函数动态开辟的空间,在使用完毕后未释放,结果导致一直占据该内存单元。直到程序结束。即所谓内存泄漏。...
  • qq_18738333
  • qq_18738333
  • 2017年04月10日 21:26
  • 209

Android开发中常见的5大内存泄漏问题及解决办法

在android开发中,内存泄漏是比较常见的问题,有过一些android编程经历的童鞋应该都遇到过,但为什么会出现内存泄漏呢?内存泄漏又有什么影响呢? 在android程序开发中,当一个对象已经...
  • qq_17010193
  • qq_17010193
  • 2017年08月05日 16:23
  • 150

Handler使用引起的内存泄漏原因以及解决办法

问题来源在之前我的一篇文章中我就指出了我在项目中如何会出现 内存泄漏的问题的,有兴趣的小伙伴可以点击获取原文看看这个问题出现的来龙去脉,在这里我就不过多做说明了。下面我们用最简单直接粗暴的方式进入主题...
  • lqw_student
  • lqw_student
  • 2016年10月28日 11:38
  • 1057

Android开发中常见的内存泄漏情况和解决办法

什么是内存泄漏?答:在Android程序开发中,当一个对象已经不需要再使用了,本该被回收时,而另外一个正在使用的对象持有它的引用从而导致它不能被回收,这就导致本该被回收的对象不能被回收而停留在堆内存中...
  • da_caoyuan
  • da_caoyuan
  • 2017年08月08日 17:49
  • 474

Android开发常见的Activity中内存泄漏及解决办法

上一篇文章楼主提到由Context引发的内存泄漏,在这一篇文章里,我们来谈谈Android开发中常见的Activity内存泄漏及解决办法。本文将会以“为什么”“怎么解决”的方式来介绍这几种内存泄漏。 ...
  • wwlwwy89
  • wwlwwy89
  • 2017年06月28日 14:24
  • 84
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:浅析C/C++内存泄漏的解决办法
举报原因:
原因补充:

(最多只允许输入30个字)