天天看點

動态記憶體配置設定、記憶體洩漏及檢測

動态記憶體配置設定

所謂動态記憶體配置設定(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++等等,随着代碼量的增長,記憶體洩漏這種問題幾乎是無法避免的,這時我們可以利用這些工具比較便捷找到問題所在.

繼續閱讀