最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C++中new和delete匹配使用過(guò)程詳解

 更新時(shí)間:2023年02月14日 10:58:47   作者:[Pokemon]大貓貓  
關(guān)于 new 和 delete 的使用相信大家并不陌生,可是為什么使用 new 的時(shí)候要用 delete,使用 new[] 的時(shí)候又要用 delete[]呢?本文就來(lái)和大家詳細(xì)說(shuō)說(shuō)

C語(yǔ)言的動(dòng)態(tài)內(nèi)存管理函數(shù)(malloc、calloc、realloc、free) 雖然可以繼續(xù)在 C++ 使用,但是對(duì)于自定義類型成員而言,這些函數(shù)不會(huì)自動(dòng)調(diào)用構(gòu)造函數(shù)和析構(gòu)函數(shù),于是 C++ 增加了 new 和 delete 關(guān)鍵字

一、new和delete的使用

new 和 delete 用于在堆上申請(qǐng)或釋放一個(gè)元素的空間,new[] 和 delete[] 用于在堆上申請(qǐng)或釋放一塊連續(xù)的空間,對(duì)于自定義類型空間的開(kāi)辟,new 和 delete 還會(huì)調(diào)用構(gòu)造函數(shù)和析構(gòu)函數(shù)

#include <iostream>
using namespace std;
class Demo
{
public:
	Demo(int a1 = 10, int a2 = 20)
		: _a1(a1)
		, _a2(a2)
	{
		cout << "Demo()" << endl;
	}
	void print()
	{
		cout << _a1 << " " << _a2 << endl;
	}
	~Demo()
	{
		cout << "~Demo()" << endl;
	}
private:
	int _a1;
	int _a2;
};
void printIntArr(int* arr, int len)
{
	for (int i = 0; i < len; ++i)
	{
		cout << arr[i] << " ";
	}
	cout << endl;
}
void printDemoArr(Demo* arr, int len)
{
	for (int i = 0; i < len; ++i)
	{
		arr[i].print();
	}
	cout << endl;
}
int main()
{
	//用 new 申請(qǐng)一個(gè)內(nèi)置類型變量的空間
	int* pint1 = new int;
	cout << *pint1 << endl; //輸出 -842150451
	//使用括號(hào)中的值初始化變量
	int* pint2 = new int(5);
	cout << *pint2 << endl;	//輸出 5
	//用 delete 釋放一個(gè)變量的空間
	delete pint1;
	delete pint2;
	//用 new 申請(qǐng)一個(gè)自定義類型對(duì)象的空間,申請(qǐng)后會(huì)自動(dòng)調(diào)用構(gòu)造函數(shù)
	Demo* pd1 = new Demo;	//輸出 Demo()
	pd1->print();	//輸出 10 20
	//自定義類型會(huì)根據(jù)括號(hào)中的參數(shù)調(diào)用對(duì)應(yīng)的構(gòu)造函數(shù)
	Demo* pd2 = new Demo(5, 5);	//輸出 Demo()
	pd2->print();	//輸出 5 5
	//用 delete 釋放一個(gè)變量的空間,釋放前會(huì)自動(dòng)調(diào)用析構(gòu)函數(shù)
	delete pd1;	//輸出 ~Demo()
	delete pd2;	//輸出 ~Demo()
	//對(duì)內(nèi)置類型用 new[] 開(kāi)辟一塊連續(xù)的空間
	int* pint3 = new int[5];	//[]中表示開(kāi)辟整形的個(gè)數(shù)
	printIntArr(pint3, 5);	//輸出 -842150451 -842150451 -842150451 -842150451 -842150451
	//用花括號(hào)中的值初始化開(kāi)辟的連續(xù)空間,未給值的為 0
	int* pint4 = new int[5]{ 1, 2, 3, 4 };	
	printIntArr(pint4, 5);	//輸出 1 2 3 4 0
	//對(duì)內(nèi)置類型用 delete[] 釋放一塊連續(xù)的空間
	delete[] pint3;
	delete[] pint4;
	//對(duì)自定義類型用 new[] 開(kāi)辟一塊連續(xù)的空間
	//申請(qǐng)后會(huì)對(duì)空間自動(dòng)調(diào)用構(gòu)造函數(shù) 5 次
	Demo* pd3 = new Demo[5];	//輸出 5 行 Demo()
	printDemoArr(pd3, 5);	//輸出 5 行 10 20
	//用花括號(hào)中的值初始化開(kāi)辟的連續(xù)空間
	//花括號(hào)中如果用小括號(hào)會(huì)被認(rèn)為是逗號(hào)表達(dá)式,會(huì)去調(diào)用單參的構(gòu)造函數(shù)
	//調(diào)用多參構(gòu)造函數(shù)應(yīng)在花括號(hào)中使用花括號(hào),未給的值根據(jù)構(gòu)造函數(shù)決定
	Demo* pd4 = new Demo[5]{ (1, 2), {5}, {5, 10}};	//輸出 5 行 Demo()
	printDemoArr(pd4, 5);	//輸出 第一行 2 20,第二行 5 10 第三行 5 10,兩行 10 20
	//對(duì)自定義類型用 delete[] 釋放一塊連續(xù)的空間
	//釋放之前會(huì)對(duì)空間自動(dòng)調(diào)用析構(gòu)函數(shù) 5 次
	delete[] pd3;	//輸出 5 行 ~Demo
	delete[] pd4;	//輸出 5 行 ~Demo
	return 0;
}

二、operator new和operator delete函數(shù)

operator new 和 operator delete 是系統(tǒng)提供的全局函數(shù),不是 new 和 delete 的運(yùn)算符重載函數(shù)

  • operator new 底層是通過(guò) malloc 函數(shù)來(lái)申請(qǐng)空間,當(dāng)空間申請(qǐng)成功時(shí)直接返回,失敗時(shí)拋出異常(不會(huì)返回 nullptr),operator new 函數(shù)可以像 malloc 一樣使用,只是失敗時(shí)的處理不同
  • operator delete 和 free 底層都是是通過(guò) _free_dbg 函數(shù)釋放空間,只不過(guò) operator delete 會(huì)對(duì)釋放前后進(jìn)行一些檢查
#include <iostream>
using namespace std;
int main()
{
	//operator new 和 malloc 使用方法一樣
	//operator new 申請(qǐng)空間失敗時(shí)拋異常
	int* pi = (int*)operator new(sizeof(int) * 4);
	//operator delete 和 free 使用方法一樣,都會(huì)調(diào)用 _free_dbg
	//operator delete 在釋放空間時(shí)會(huì)做一些檢查
	operator delete(pi);
	return 0;
}

operator new[] 和 operator delete[] 也是系統(tǒng)提供的全局函數(shù),內(nèi)部是通過(guò)調(diào)用 operator new 和 operator delete 函數(shù)

三、new和delete的實(shí)現(xiàn)原理

如果是內(nèi)置類型,new 和 delete 調(diào)用 operator new 和 operator delete,new[] 和 delete[] 調(diào)用 operator new[] 和 operator delete[]

如果是自定義類型:

#include <iostream>
using namespace std;
class Demo
{
public:
	Demo(int a1 = 10, int a2 = 20);
	~Demo();
private:
	int _a1;
	int _a2;
};
Demo::Demo(int a1, int a2)
	: _a1(a1)
	, _a2(a2)
{
	cout << "Demo()" << endl;
}
Demo::~Demo()
{
	cout << "~Demo()" << endl;
}
int main()
{
	Demo* pd1 = new Demo(5, 5);
	delete pd1;
	Demo* pd2 = new Demo[2]{ {1, 2}, {2, 3} };
	delete[] pd2;
	return 0;
}

new:

1. 調(diào)用 operator new 函數(shù)申請(qǐng)空間

2. 在申請(qǐng)的空間上執(zhí)行構(gòu)造函數(shù),完成對(duì)象的構(gòu)造

delete:

1. 在空間上執(zhí)行析構(gòu)函數(shù),完成對(duì)象中資源的清理工作

2. 調(diào)用operator delete函數(shù)釋放對(duì)象的空間

new 類型[N]:

1. 調(diào)用operator new[] 函數(shù),實(shí)際上是在 operator new[] 中調(diào)用 operator new 函數(shù)完成 N 個(gè)對(duì)象空間的申請(qǐng)

2. 在申請(qǐng)的空間上執(zhí)行 N 次構(gòu)造函數(shù)

delete[]:

1. 在釋放的對(duì)象空間上執(zhí)行 N 次析構(gòu)函數(shù),完成 N 個(gè)對(duì)象中資源的清理

2. 調(diào)用 operator delete[] 釋放空間,實(shí)際上時(shí)在 operator delete[] 中調(diào)用 operator delete 來(lái)釋放空間

四、申請(qǐng)空間和釋放空間應(yīng)配套使用

malloc/free、new/delete、new[]/delete[] 需要配套使用,否則總會(huì)有出問(wèn)題的時(shí)候

下述代碼不會(huì)報(bào)錯(cuò),會(huì)產(chǎn)生內(nèi)存泄漏

#include <iostream>
using namespace std;
class Stack
{
public:
	Stack(int capacity = 4)
		: _a(new int[capacity])
		, _top(0)
		, _capacity(capacity)
	{
	}
	~Stack()
	{
		if (_a)
		{
			delete[] _a;
			_top = _capacity = 0;
		}
	}
private:
	int* _a;
	int _top;
	int _capacity;
};
int main()
{
	Stack* ps = new Stack;
	//free(ps);	//內(nèi)存泄漏
	//delete 釋放內(nèi)存之前會(huì)調(diào)用析構(gòu)函數(shù)
	delete ps;	//正確寫(xiě)法
	return 0;
}

下述代碼在 vs2022 下會(huì)崩潰

#include <iostream>
using namespace std;
class A
{
public:
	A(int a = 0)
		: _a(a)
	{
		cout << "A():" << endl;
	}
	~A()
	{
		cout << "~A():" << endl;
	}
private:
	int _a;
};
int main()
{
	A* p1 = new A[10];
	//free(p1); 	//崩潰
	delete[] p1;	//正確寫(xiě)法
	A* p2 = new A[10];
	//delete p2;	 //崩潰
	delete[] p2;	//正確寫(xiě)法
	return 0;
}

注意:不同的編譯器處理可能不同,這里只代表在 vs2022 編譯器中

五、定位new表達(dá)式

定位 new 表達(dá)式是在已開(kāi)辟好的原始內(nèi)存空間上調(diào)用構(gòu)造函數(shù)初始化一個(gè)對(duì)象,使用格式:

new(place_address)type 或者 new(place_address)type(initializer-list)
place_address 必須是一個(gè)指針,initializer-list 是類型的初始化列表

定位 new 表達(dá)式在實(shí)際中一般是配合 內(nèi)存池 使用,因?yàn)閮?nèi)存池分配出的內(nèi)存沒(méi)有初始化,并且構(gòu)造函數(shù)不可以顯示調(diào)用,所以如果是自定義類型的對(duì)象,需要使用定位 new 以進(jìn)行顯示調(diào)用構(gòu)造函數(shù)進(jìn)行初始化

#include <iostream>
using namespace std;
class A
{
public:
	A(int a = 0)
		: _a(a)
	{
		cout << "A()" << endl;
	}
	~A()
	{
		cout << "~A()" << endl;
	}
private:
	int _a;
};
//定位 new 又叫 replacement new
int main()
{
	//p1 現(xiàn)在指向的只是與 A 對(duì)象相同大小的一段空間,并不是一個(gè)對(duì)象,因?yàn)闆](méi)有調(diào)用構(gòu)造函數(shù)
	A* p1 = (A*)malloc(sizeof(A));
	new(p1)A;	//調(diào)用無(wú)參的構(gòu)造函數(shù) 輸出 A()
	//可以手動(dòng)調(diào)用析構(gòu)函數(shù),然后釋放空間
	p1->~A();	//輸出 ~A()
	free(p1);
	//p2 現(xiàn)在指向的只是與 A 對(duì)象相同大小的一段空間,并不是一個(gè)對(duì)象,因?yàn)闆](méi)有調(diào)用構(gòu)造函數(shù)
	A* p2 = (A*)operator new(sizeof(A));
	new(p2)A(10);	//10 是參數(shù),可以根據(jù)參數(shù)調(diào)用對(duì)應(yīng)的構(gòu)造函數(shù) 輸出 A()
	p2->~A();	//輸出 ~A()
	operator delete(p2);
	return 0;
}

六、malloc/free和new/delete的區(qū)別

malloc/free 和 new/delete 的共同點(diǎn)是:都是從堆上申請(qǐng)空間,并且需要用戶手動(dòng)釋放

不同的地方是:

  • malloc 和 free 是函數(shù),new 和 delete 是運(yùn)算符
  • malloc 申請(qǐng)的空間不會(huì)初始化,new 可以初始化
  • malloc 申請(qǐng)空間時(shí),需要手動(dòng)計(jì)算空間大小并傳遞,new 只需在其后跟上空間的類型,如果是多個(gè)對(duì)象,[] 中指定對(duì)象個(gè)數(shù)即可
  • malloc 的返回值為 void*,接收時(shí)必須強(qiáng)制類型轉(zhuǎn)換,new 不需要,因?yàn)?new 后跟的是空間的類型
  • malloc 申請(qǐng)空間失敗時(shí),返回的是NULL,因此使用時(shí)必須判空,new 不需要,但是 new 需要捕獲異常
  • 申請(qǐng)自定義類型對(duì)象時(shí),malloc/free 只會(huì)開(kāi)辟空間,不會(huì)調(diào)用構(gòu)造函數(shù)與析構(gòu)函數(shù),而 new 在申請(qǐng)空間后會(huì)調(diào)用構(gòu)造函數(shù)完成對(duì)象的初始化,delete 在釋放空間前會(huì)調(diào)用析構(gòu)函數(shù)完成空間中資源的清理

到此這篇關(guān)于C++中new和delete匹配使用過(guò)程詳解的文章就介紹到這了,更多相關(guān)C++ new與delete內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 最新C語(yǔ)言中g(shù)etchar的使用

    最新C語(yǔ)言中g(shù)etchar的使用

    getchar()是在輸入緩沖區(qū)順序讀入一個(gè)字符(包括空格、回車和Tab) ,getchar()是stdio.h中的庫(kù)函數(shù),它的作用是從stdin流中讀入一個(gè)字符,本文給大家介紹getchar的使用,感興趣的朋友跟隨小編一起看看吧
    2022-12-12
  • google c++程序測(cè)試框架googletest使用教程詳解

    google c++程序測(cè)試框架googletest使用教程詳解

    &#8203;GoogleTest 是 Google 的 C++ 測(cè)試和模擬框架,可以幫助程序員測(cè)試C++程序的結(jié)果預(yù)期,這篇文章主要介紹了google c++程序測(cè)試框架googletest使用教程,需要的朋友可以參考下
    2021-08-08
  • C語(yǔ)言新手入門速通手冊(cè)

    C語(yǔ)言新手入門速通手冊(cè)

    C 語(yǔ)言是一種通用的、面向過(guò)程式的計(jì)算機(jī)程序設(shè)計(jì)語(yǔ)言。1972 年,為了移植與開(kāi)發(fā) UNIX 操作系統(tǒng),丹尼斯·里奇在貝爾電話實(shí)驗(yàn)室設(shè)計(jì)開(kāi)發(fā)了 C 語(yǔ)言。C 語(yǔ)言是一種廣泛使用的計(jì)算機(jī)語(yǔ)言,它與 Java 編程語(yǔ)言一樣普及,二者在現(xiàn)代軟件程序員之間都得到廣泛使用
    2022-04-04
  • QT實(shí)現(xiàn)年會(huì)抽獎(jiǎng)小軟件的示例代碼

    QT實(shí)現(xiàn)年會(huì)抽獎(jiǎng)小軟件的示例代碼

    本文主要介紹了QT實(shí)現(xiàn)年會(huì)抽獎(jiǎng)小軟件的示例代碼,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-01-01
  • 利用Matlab實(shí)現(xiàn)時(shí)域分析功能的示例詳解

    利用Matlab實(shí)現(xiàn)時(shí)域分析功能的示例詳解

    利用MATLAB可以方便地進(jìn)行控制系統(tǒng)的時(shí)域分析。這篇文章主要通過(guò)簡(jiǎn)單的示例為大家介紹了Matlab進(jìn)行時(shí)域分析的具體操作,需要的可以參考一下
    2023-02-02
  • C語(yǔ)言實(shí)現(xiàn)簡(jiǎn)單的停車場(chǎng)管理系統(tǒng)

    C語(yǔ)言實(shí)現(xiàn)簡(jiǎn)單的停車場(chǎng)管理系統(tǒng)

    這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言實(shí)現(xiàn)簡(jiǎn)單的停車場(chǎng)管理系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-03-03
  • C語(yǔ)言實(shí)現(xiàn)三子棋游戲

    C語(yǔ)言實(shí)現(xiàn)三子棋游戲

    這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言實(shí)現(xiàn)三子棋游戲的方法,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-01-01
  • 基于C++中覆蓋,重載,隱藏的一點(diǎn)重要說(shuō)明

    基于C++中覆蓋,重載,隱藏的一點(diǎn)重要說(shuō)明

    下面小編就為大家?guī)?lái)一篇基于C++中覆蓋,重載,隱藏的一點(diǎn)重要說(shuō)明。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2016-12-12
  • QT中對(duì)Mat類的一些操作詳解

    QT中對(duì)Mat類的一些操作詳解

    本文主要介紹了QT中對(duì)Mat類的一些操作詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2022-06-06
  • Qt模仿Windows文件夾縮略圖的三種實(shí)現(xiàn)方式

    Qt模仿Windows文件夾縮略圖的三種實(shí)現(xiàn)方式

    本文講的不是簡(jiǎn)單的model/view或者widget的或者QML的基礎(chǔ)框架實(shí)現(xiàn),而是在這些框架之上的肉(文件夾縮略圖)的效果實(shí)現(xiàn),本文將以QWidget、Qt Quick(QML)、以及QGraph三種實(shí)現(xiàn)方式來(lái)講解,如何做出和Windows類似的縮略圖,需要的朋友可以參考下
    2024-04-04

最新評(píng)論

调兵山市| 琼海市| 墨竹工卡县| 安陆市| 安福县| 滁州市| 深州市| 博野县| 来宾市| 滁州市| 股票| 司法| 句容市| 图木舒克市| 桐城市| 察雅县| 沽源县| 彰武县| 依安县| 耒阳市| 长葛市| 页游| 合山市| 新竹县| 西和县| 土默特右旗| 攀枝花市| 凤翔县| 连山| 盖州市| 沙湾县| 西畴县| 马鞍山市| 防城港市| 游戏| 黄龙县| 湘潭市| 吉隆县| 上犹县| 怀宁县| 布拖县|