国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > C++ > 正文

C++中delete和delete[]的區別和深入分析

2019-11-06 08:46:12
字體:
來源:轉載
供稿:網友

在C++中經常遇到內存的開辟和釋放問題,最近在做項目的時候遇到了一個關于new和delete內存釋放的問題,所以總結下這個問題。在C++ PRimer中,delete一般用來釋放單個對象的內存,delete[]用來釋放多個對象的內存。但是實際的情況比較復雜,特別是涉及到自己定義的類以及類中還有指針內存開辟的問題的時候。以下分三種情況來討論。

一、基本數據類型指針的內存的開辟和釋放。

針對基本數據類型的指針的內存開辟和釋放,delete和delete[]沒有任何區別,都可以實現對內存的釋放。eg:

int* pdata = new int [10];	delete[] pdata;	//情況1	pdata = new int [10];	delete pdata;	//情況2	pdata = new int;	delete pdata;	//情況3	pdata = new int;	delete[]  pdata;//情況4

以上四種情況都可以,都可以通過編譯并釋放指針pdata所開辟的內存。

二、自定義的類對象指針的內存和開辟和釋放(類中沒有內存的開辟)。

針對這種情況,delete和delete[]就有了區別。看以下例程:

類的聲明如下:

class CImage{public:	int width;	int height;	CImage(int w, int h);	CImage();	~CImage();};CImage::CImage(){	cout << "構造函數2被執行" << endl;}CImage::CImage(int w, int h){	width = w;	height =h;	cout << "構造函數1被執行" << endl;}CImage::~CImage(){	cout << "析構函數被執行" << endl;}主函數如下:

{	CImage* pImg = new CImage[10];	delete pImg;	//情況1	CImage* pImg = new CImage[10];	delete[] pImg;;	//情況2	CImage* pImg = new CImage(3, 4);	delete[] pImg;	//情況3	CImage* pImg = new CImage(3, 4);	delete pImg;//情況4	cout << "通過編譯" << endl;	cin.get();}情況1:不能執行成功,類的析構函數就執行一次;

情況2:可以執行成功,類的析構函數就執行十次;

情況3:不能執行成功,沒有執行類的析構函數;

·情況4:可以執行成功,類的析構函數就執行一次;

總結:如果是針對自定義的類對象指針的內存和開辟和釋放(類中沒有內存的開辟時),單個對象的內存的開辟必須用delete來釋放,多個對象內存的開辟必須用delete[]來釋放。

三、自定義的類對象指針的內存和開辟和釋放(類中有內存的開辟)。

類的聲明如下:

class CImage{public:	int width;	int height;	CImage(int w, int h);	CImage();	~CImage();	int * pImageData;};CImage::CImage(){	pImageData = NULL;	cout << "構造函數2被執行" << endl;}CImage::CImage(int w, int h){	width = w;	height =h;	pImageData = new int[width*height];	cout << "構造函數1被執行" << endl;}CImage::~CImage(){	if(pImageData != NULL)	{		cout << "對象內內存被釋放" << endl;		delete[] pImageData;		pImageData = NULL;			}	cout << "析構函數被執行" << endl;}主函數如下:

{	//情況1	CImage* pImg = new CImage[11];	pImg[0].pImageData = new int [100];	pImg[2].pImageData = new int [100];	delete[] pImg;			//情況2	CImage* pImg = new CImage[11];	pImg[0].pImageData = new int [100];	pImg[2].pImageData = new int [100];	delete pImg;		//情況3	CImage* pImg = new CImage(3, 4);	pImg->pImageData = new int [100];	delete pImg;	//情況4	CImage* pImg = new CImage(3, 4);	pImg->pImageData = new int [100];	delete[] pImg;}情況1:可以執行,執行了十次構造函數,十次析構函數,同時pImg[0]和pImg[2]對象中pImageData的內存被釋放。

情況2:不能執行成功,執行了十次構造函數,一次析構函數,程序停頓。

情況3:可移執行,執行了一次構造函數,一次析構函數,pImg對象中pImageData的內存被釋放。

情況4:不能執行成功,執行了一次構造函數,程序停頓。

總結:如果是針對自定義的類對象指針的內存和開辟和釋放(類中有內存的開辟時),單個對象的內存的開辟必須用delete來

釋放,多個對象內存的開辟必須用delete[]來釋放。注意:這種情況下,delete[]和delete都自動能調用類的析構函數,這樣的話,

在類的析構函數中就需要添加釋放對象中指針開辟內存的代碼。

更近一步:針對下面兩種情況都可以順利執行:

//情況1	CImage* pImg = new CImage(3, 4);	pImg->pImageData = new int [100];	delete pImg->pImageData;	pImg->pImageData = NULL;	delete pImg;		//情況2	CImage* pImg = new CImage(3, 4);	pImg->pImageData = new int [100];	delete pImg;情況1中,在釋放pImg指針內存之前將其成員指針的內存先釋放,這樣不會有影響;情況2中直接釋放pImg指針內存,這樣,對象的析構函數會自

動被調用。但是:在情況2中,如果我們的析構函數中沒有釋放內存的語句,這種情況很容易造成內存泄漏。


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表

圖片精選

主站蜘蛛池模板: 雷波县| 略阳县| 永德县| 松桃| 兴文县| 威海市| 上蔡县| 永昌县| 屏东县| 小金县| 凤山县| 周至县| 彭泽县| 潞城市| 松潘县| 乐山市| 景谷| 容城县| 黎城县| 琼结县| 新郑市| 建阳市| 黔西| 垫江县| 榆林市| 四子王旗| 台中县| 泰和县| 定结县| 海城市| 镇安县| 息烽县| 茂名市| 青川县| 合川市| 凉城县| 鹤峰县| 运城市| 洪泽县| 陆河县| 邵阳市|