如何定位内存泄漏问题

Things You‘ll Need

  • Proficiency in C++
  • C++ compiler
  • Debugger and other investigative software tools

1

Understand the operator basics. The C++ operator "new" allocates heap memory. The "delete" operator frees heap memory. For every "new," you should use a "delete" so that you free the same memory you allocated:

char* str = new char [30]; // Allocate 30 bytes to house a string.

delete [] str; // Clear those 30 bytes and make str point nowhere.

2

Reallocate memory only if you‘ve deleted. In the code below, str acquires a new address with the second allocation. The first address is lost irretrievably, and so are the 30 bytes that it pointed to. Now they‘re impossible to free, and you have a memory leak:

char* str = new char [30]; // Give str a memory address.

// delete [] str; // Remove the first comment marking in this line to correct.

str = new char [60]; /* Give str another memory address with
                                                    the first one gone forever.*/

delete [] str; // This deletes the 60 bytes, not just the first 30.

3

Watch those pointer assignments. Every dynamic variable (allocated memory on the heap) needs to be associated with a pointer. When a dynamic variable becomes disassociated from its pointer(s), it becomes impossible to erase. Again, this results in a memory leak:

char* str1 = new char [30];

char* str2 = new char [40];

strcpy(str1, "Memory leak");

str2 = str1; // Bad! Now the 40 bytes are impossible to free.

delete [] str2; // This deletes the 30 bytes.

delete [] str1; // Possible access violation. What a disaster!

4

Be careful with local pointers. A pointer you declare in a function is allocated on the stack, but the dynamic variable it points to is allocated on the heap. If you don‘t delete it, it will persist after the program exits from the function:

void Leak(int x){

char* p = new char [x];

// delete [] p; // Remove the first comment marking to correct.

}

5

Pay attention to the square braces after "delete." Use "delete" by itself to free a single object. Use "delete" [] with square brackets to free a heap array. Don‘t do something like this:

char* one = new char;

delete [] one; // Wrong

char* many = new char [30];

delete many; // Wrong!

6

If the leak yet allowed - I‘m usually seeking it with deleaker (check it here: http://deleaker.com).

Thanks!

发生内存错误是件非常麻烦的事情。编译器不能自动发现这些错误,通常是在程序运行时才能捕捉到。而这些错误大多没有明显的症状,时隐时现,增加了改错的难度。

常见的内存错误及其对策如下:

(1)      内存分配未成功,却使用了它。

编程新手常犯这种错误,因为他们没有意识到内存分配会不成功。常用解决办法是,在使用内存之前检查指针是否为NULL。如果指针p是函数的参数,那么在函数的入口处用assert(p!=NULL)进行检查。如果是用malloc或new来申请内存,应该用if(p==NULL) 或if(p!=NULL)进行防错处理。

(2)      内存分配虽然成功,但是尚未初始化就引用它。

犯这种错误主要有两个起因:一是没有初始化的观念;二是误以为内存的缺省初值全为零,导致引用初值错误(例如数组)。 内存的缺省初值究竟是什么并没有统一的标准,尽管有些时候为零值,我们宁可信其无不可信其有。所以无论用何种方式创建数组,都别忘了赋初值,即便是赋零值也不可省略,不要嫌麻烦。

(3)      内存分配成功并且已经初始化,但操作越过了内存的边界。

例如在使用数组时经常发生下标“多1”或者“少1”的操作。特别是在for循环语句中,循环次数很容易搞错,导致数组操作越界。

(4)      忘记了释放内存,造成内存泄露。

含有这种错误的函数每被调用一次就丢失一块内存。刚开始时系统的内存充足,你看不到错误。终有一次程序突然死掉,系统出现提示:内存耗尽。

动态内存的申请与释放必须配对,程序中malloc与free的使用次数一定要相同,否则肯定有错误(new/delete同理)。

(5)      释放了内存却继续使用它。

有三种情况:

A.        程序中的对象调用关系过于复杂,实在难以搞清楚某个对象究竟是否已经释放了内存,此时应该重新设计数据结构,从根本上解决对象管理的混乱局面

B.        函数的return语句写错了,注意不要返回指向“栈内存”的“指针”或者“引用”,因为该内存在函数体结束时被自动销毁

C.        使用free或delete释放了内存后,没有将指针设置为NULL。导致产生“野指针”。

时间: 2024-11-06 00:03:40

如何定位内存泄漏问题的相关文章

如何查看程序是否有内存泄漏,并且定位内存泄漏代码位置(VC++)

1.什么是内存泄漏? 内存泄漏指的是在程序里动态申请的内存在使用完后,没有进行释放,导致这部分内存没有被系统回收,久而久之,可能导致程序内存不断增大,系统内存不足--引发一系列灾难性后果:(关于程序申请内存分配方式,详见:内存分配方式) 2.零容忍 排除内存泄漏对于程序的稳健型特别重要,尤其是程序需要长时间.稳定地运行时.C++这类动态内存申请释放都是由程序员控制的语言,稍不注意,很有可能就会有未释放的内存.这类问题,虽然有的时候仅仅只是泄漏了几个字节,但是危害极大.因此,我们一般都是要做到:内

VS2015 定位内存泄漏工具vld

介绍一款在vs2015开发环境定位内存泄漏工具:Visual Leak Detector ,具体的使用方法如下: 1.  安装vld-2.5-setup.exe (下载链接地址后面会给出),安装过程会出现以下界面,所以复选框均 选中. 图1 vld安装显示界面 2. 利用 vs2015新建一个控制台程序,代码如下图所示: 图2 示例代码片段 如图2所示,只要将vld头文件引入到工程即可.vld.路径以及vld动态库VS2015可自动找到,不需要指定路径. 程序运行的结果如图3所示: 原文地址:h

使用CRT定位内存泄漏

1. 使能内存泄漏检测#define _CRTDBG_MAP_ALLOC#include <stdlib.h>#include <crtdbg.h>注1:语句顺序不能修改:注2:仅对DEBUG版本有效注3:#define语句可以去掉,但leak dump会丢失细节信息,如:泄漏的代码文件及行号 2. 打印泄漏内存报告在合适的地方调用下面的语句,即可看到内存泄漏报告:_CrtDumpMemoryLeaks(); 3. 如果应用程序有多个出口,可 以通过设置调试标志自动在程序退出时打印

vs 2017/2015/2013 如何定位C++内存泄漏

定位内存泄漏是C++的一个大问题 我们可以通过如下方式进行定位: //在主函数文件中加入如下代码 #include <stdlib.h> #include <crtdbg.h> #ifdef _DEBUG #define new new(_NORMAL_BLOCK, __FILE__, __LINE__) #endif void EnableMemLeakCheck() { int tmpFlag = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG); tmp

(转)java内存泄漏的定位与分析

转自:http://blog.csdn.net/x_i_y_u_e/article/details/51137492 1.为什么会发生内存泄漏 java 如何检测内在泄漏呢?我们需要一些工具进行检测,并发现内存泄漏问题,不然很容易发生down机问题. 编写java程序最为方便的地方就是我们不需要管理内存的分配和释放,一切由jvm来进行处理,当java对象不再被应用时,等到堆内存不够用时,jvm会进行垃圾回收,清除这些对象占用的堆内存空间,如果对象一直被应用,jvm无法对其进行回收,创建新的对象时

java内存泄漏的定位与分析

1.为什么会发生内存泄漏 java 如何检测内在泄漏呢?我们需要一些工具进行检测,并发现内存泄漏问题,不然很容易发生down机问题. 编写java程序最为方便的地方就是我们不需要管理内存的分配和释放,一切由jvm来进行处理,当java对象不再被应用时,等到堆内存不够用时,jvm会进行垃圾回收,清除这些对象占用的堆内存空间,如果对象一直被应用,jvm无法对其进行回收,创建新的对象时,无法从Heap中获取足够的内存分配给对象,这时候就会导致内存溢出.而出现内存泄露的地方,一般是不断的往容器中存放对象

如何定位 Node.js 的内存泄漏

基础知识 Node.js 进程的内存管理,都是有 V8 自动处理的,包括内存分配和释放.那么 V8 什么时候会将内存释放呢? 在 V8 内部,会为程序中的所有变量构建一个图,来表示变量间的关联关系,当变量从根节点无法触达时,就意味着这个变量不会再被使用了,就是可以回收的了.而这个回收是一个过程性的,从快速 GC 到 最后的 Full GC,是需要一段时间的.另外,Full GC 是有触发阈值的,所以可能会出现内存长期占用在一个高值,也可以算是一种内存泄漏,可以从<一次 Node.js 应用内存暴

使用Xcode Instruments Leak解决内存泄漏问题

iOS 5.0之后apple引入了Xcode编译器特性ARC(Automatic Reference Counting,自动引用计数)来帮助开发者管理内存,但为了追求app的高性能与减少安装包大小,工作中很多时候需要我们手动管理内存.再牛的开发者也不能保证自己写的code 100%没有内存泄露,出现内存泄露不可怕,可怕的是我们时间与精力花了大把,但内存泄露依旧没解决,即影响了工作效率也影响自己的心情. 下面就讲解xcode中的内存调试神器---Instruments Leak ,不管是ios开发

检测内存泄漏

iOS 5.0之后apple引入了Xcode编译器特性ARC(Automatic Reference Counting,自动引用计数)来帮助开发者管理内存,但为了追求app的高性能与减少安装包大小,工作中很多时候需要我们手动管理内存.再牛的开发者也不能保证自己写的code 100%没有内存泄露,出现内存泄露不可怕,可怕的是我们时间与精力花了大把,但内存泄露依旧没解决,即影响了工作效率也影响自己的心情. 下面就讲解xcode中的内存调试神器---Instruments Leak ,不管是ios开发