天天看点

动态内存分配、内存泄漏及检测

动态内存分配

所谓动态内存分配(Dynamic Memory Allocation)就是指在程序执行的过程中动态地分配或者回收存储空间的分配内存的方法。动态内存分配不象数组等静态内存分配方法那样需要预先分配存储空间,而是由系统根据程序的需要即时分配,且分配的大小就是程序要求的大小。

在c中,动态内存分配使用malloc与free来分配内存和释放内存.用法为:

void *malloc(size_t size);
void free(void *ptr);
           

其中size为要申请空间的字节数

而在c++中,动态内存分配有新的关键字new与delete,但同时也兼容c的malloc与free,但推荐使用new与delete.

为什么呢?因为new与delete是运算符而malloc与free是函数,所以new与delete的执行效率要高些,而且new与delete可以初始化变量.

#include <iostream>
#include <Windows.h>

using namespace std;

int main(void){
	int *a=new int(10);//动态分配一个int类型的变量,并把变量初始化为10,a指向这个变量
	cout<<*a<<endl;
	delete a;
	
	int *p=new int[5];//可以动态分配数组,但是不能在分配的同时初始化!!!
	for(int i=0;i<5;i++){//里面是随机值
		cout<<p[i]<<endl;
	}
	delete[] p;
	
	system("pause");
	return 0;
}
           
动态内存分配、内存泄漏及检测

通过以上代码及注释与运行结果,大家应该了解了它的用法,下面是总结:

  1. 在使用new关键字分配变量时可以同时进行初始化,而在分配数组时不可以.
  2. 无论是new还是malloc分配内存,在使用完后一定一定要释放内存,否则会造成内存泄漏.
  3. c++中这两种分配内存的方法可以混用,即用new分配内存,用free释放内存.

内存泄漏及检测

内存泄漏(Memory Leak)是指程序中己动态分配的堆内存由于某种原因程序未释放或无法释放,造成系统内存的浪费,导致程序运行速度减慢甚至系统崩溃等严重后果。

如何检测内存泄漏呢?看以下代码:

//包含头文件
#define _CRTDEG_MAP_ALLOC
#include <stdlib.h>
#include <crtdbg.h>
#include <iostream>
#include <Windows.h>

//接管new操作符
#ifdef _DEBUG
#ifndef DBG_NEW
#define DBG_NEW new (_NORMAL_BLOCK,__FILE__,__LINE__)
#define new DBG_NEW
#endif
#endif

using namespace std;

int main(void){
	int *p;
	for(int i=0;i<5;i++){
		p=new int[5];//动态内存分配
	}
	
	_CrtDumpMemoryLeaks();//输出内存泄漏信息
	system("pause");
	return 0;
}
           

运行结果:

动态内存分配、内存泄漏及检测

很奇怪,对吧?什么都没输出,我们来看看IDE的输出界面:

动态内存分配、内存泄漏及检测

Detected memory leaks!检测到内存泄漏,标注了泄漏的文件,泄漏的字节长度,泄漏的位置.我调用了五次new操作符且未回收,所以它报了五次内存泄漏.

_CrtDumpMemoryLeaks();

的作用:当它执行时,所有未销毁的对象均会报内存泄漏.所以我们最好在程序将要结束的时候使用它.

要实现检测分三步:

1.包含头文件(宏定义是为了输出内存泄漏发生在哪个文件)

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

2.接管new操作符

#ifdef _DEBUG
#ifndef DBG_NEW
#define DBG_NEW new (_NORMAL_BLOCK,__FILE__,__LINE__)
#define new DBG_NEW
#endif
#endif
           

3.调用

以上的方法实际上是使用了CRT库,对于内存泄漏的检测,其实有很多工具,比如:MallocDebug,Valgrind,Kcachegrind,dmalloc,NuMega,BoundsCheck,ParaSoft,Insure++等等,随着代码量的增长,内存泄漏这种问题几乎是无法避免的,这时我们可以利用这些工具比较便捷找到问题所在.

继续阅读