柚子快報(bào)激活碼778899分享:C++的內(nèi)存管理
柚子快報(bào)激活碼778899分享:C++的內(nèi)存管理
感謝大佬的光臨各位,希望和大家一起進(jìn)步,望得到你的三連,互三支持,一起進(jìn)步
個(gè)人主頁(yè):LaNzikinh-CSDN博客
收入專欄:C++_LaNzikinh籃子的博客-CSDN博客
文章目錄
前言一.內(nèi)存的劃分二.C語(yǔ)言中的中動(dòng)態(tài)內(nèi)存管理方式三.C++內(nèi)存管理方式四.operator new與operator delete函數(shù)五.malloc/free和new/delete的區(qū)別總結(jié)
前言
前面完成了對(duì)日期類的實(shí)現(xiàn)和習(xí)題,現(xiàn)在我們來(lái)看看C++中內(nèi)存的管理和C++的模板這個(gè)特性
一.內(nèi)存的劃分
在C++中,內(nèi)存分成5個(gè)區(qū),他們分別是堆、棧、自由存儲(chǔ)區(qū)、全局/靜態(tài)存儲(chǔ)區(qū)和常量存儲(chǔ)區(qū)。
棧,在執(zhí)行函數(shù)時(shí),函數(shù)內(nèi)局部變量的存儲(chǔ)單元都可以在棧上創(chuàng)建,函數(shù)執(zhí)行結(jié)束時(shí)這些存儲(chǔ)單元自動(dòng)被釋放。棧內(nèi)存分配運(yùn)算內(nèi)置于處理器的指令集中,效率很高,但是分配的內(nèi)存容量有限。
堆,就是那些由new分配的內(nèi)存塊,他們的釋放編譯器不去管,由我們的應(yīng)用程序去控制,一般一個(gè)new就要對(duì)應(yīng)一個(gè)delete。如果程序員沒(méi)有釋放掉,那么在程序結(jié)束后,操作系統(tǒng)會(huì)自動(dòng)回收。
自由存儲(chǔ)區(qū),就是那些由malloc等分配的內(nèi)存塊,他和堆是十分相似的,不過(guò)它是用free來(lái)結(jié)束自己的生命的。
全局/靜態(tài)存儲(chǔ)區(qū),全局變量和靜態(tài)變量被分配到同一塊內(nèi)存中,在以前的C語(yǔ)言中,全局變量又分為初始化的和未初始化的,在C++里面沒(méi)有這個(gè)區(qū)分了,他們共同占用同一塊內(nèi)存區(qū)。
常量存儲(chǔ)區(qū),這是一塊比較特殊的存儲(chǔ)區(qū),他們里面存放的是常量,不允許修改。
二.C語(yǔ)言中的中動(dòng)態(tài)內(nèi)存管理方式
我們之前學(xué)過(guò)C語(yǔ)言中的中動(dòng)態(tài)內(nèi)存管理方式,我們現(xiàn)在來(lái)回顧一下,malloc/calloc/realloc/free,也可以看之前的文章動(dòng)態(tài)內(nèi)存管理-CSDN博客
區(qū)別:
malloc:這個(gè)函數(shù)就是像內(nèi)存申請(qǐng)一塊連續(xù)可用的空間,并且返回指向這塊空間的指針,所以我們運(yùn)用這個(gè)函數(shù)的時(shí)候必須要用一個(gè)指針去接收他,如果開(kāi)辟成功,他就會(huì)返回開(kāi)辟好的指針,如果開(kāi)辟失敗,就會(huì)返回一個(gè)空指針,因此它的返回值一定要做檢查。
calloc:這兩個(gè)函數(shù)實(shí)際上是一樣的,不管是他的初始化方式,還是他的功能都是與malloc函數(shù)是一樣的,但是唯一不同的是malloc函數(shù)開(kāi)辟的是隨機(jī)值calloc函數(shù)開(kāi)辟的空間會(huì)全部初始化把它們存放為0。
relloc:就是說(shuō)如果我之前用malloc函數(shù)開(kāi)辟的空間大小,如果我不滿意的話。我就可以用這個(gè)relloc函數(shù)來(lái)調(diào)整之前的空間大小。
缺點(diǎn):C語(yǔ)言的這種動(dòng)態(tài)開(kāi)辟,他是一種函數(shù)的調(diào)用,函數(shù)調(diào)用就會(huì)有??臻g的內(nèi)存變化。C語(yǔ)言內(nèi)存管理方式在C++中可以繼續(xù)使用,但有些地方就無(wú)能為力,而且使用起來(lái)比較麻煩,因 此C++又提出了自己的內(nèi)存管理方式:通過(guò)new和delete操作符進(jìn)行動(dòng)態(tài)內(nèi)存管
三.C++內(nèi)存管理方式
3.1內(nèi)置類型
int main()
{
// 動(dòng)態(tài)申請(qǐng)一個(gè)int類型的空間
int* ptr4 = new int;
// 動(dòng)態(tài)申請(qǐng)一個(gè)int類型的空間并初始化為10
int* ptr5 = new int(10);
// 動(dòng)態(tài)申請(qǐng)10個(gè)int類型的空間
int* ptr6 = new int[3];
delete ptr4;
delete ptr5;
delete[] ptr6;
return 0;
}
注意:申請(qǐng)和釋放單個(gè)元素的空間,使用new和delete操作符,申請(qǐng)和釋放連續(xù)的空間,使用 new[]和delete[],注意:匹配起來(lái)使用。不然會(huì)報(bào)錯(cuò)。
3.2自定義類型
class A
{
public:
A(int a = 0)
: _a(a)
{
cout << "A():" << this << endl;
}
~A()
{
cout << "~A():" << this << endl;
}
private:
int _a;
};
int main()
{
A* p1 = (A*)malloc(sizeof(A));
A* p2 = new A(1);
free(p1);
delete p2;
return 0;
}
注意:new/delete 和 malloc/free最大區(qū)別是 new/delete對(duì)于【自定義類型】除了開(kāi)空間 還會(huì)調(diào)用構(gòu)造函數(shù)和析構(gòu)函數(shù),內(nèi)置類型是幾乎是一樣的
四.operator new與operator delete函數(shù)
只要知道一點(diǎn)就是:new和delete是用戶進(jìn)行動(dòng)態(tài)內(nèi)存申請(qǐng)和釋放的操作符,operator new 和operator delete是 系統(tǒng)提供的全局函數(shù),new在底層調(diào)用operator new全局函數(shù)來(lái)申請(qǐng)空間,delete在底層通過(guò) operator delete全局函數(shù)來(lái)釋放空間。
operator new:該函數(shù)實(shí)際通過(guò)malloc來(lái)申請(qǐng)空間,當(dāng)malloc申請(qǐng)空間成功時(shí)直接返回;申請(qǐng)空間失敗,嘗試執(zhí)行空間不足應(yīng)對(duì)措施,如果改應(yīng)對(duì)措施用戶設(shè)置了,則繼續(xù)申請(qǐng),否則拋異常。
這個(gè)是源碼
void *__CRTDECL operator new(size_t size) _THROW1(_STD bad_alloc)
{
// try to allocate size bytes
void *p;
while ((p = malloc(size)) == 0)
if (_callnewh(size) == 0)
{
// report no memory
static const std::bad_alloc nomem;
_RAISE(nomem);
}
return (p);
}
void operator delete(void *pUserData)
{
_CrtMemBlockHeader * pHead;
RTCCALLBACK(_RTC_Free_hook, (pUserData, 0));
if (pUserData == NULL)
return;
_mlock(_HEAP_LOCK); /* block other threads */
__TRY
/* get a pointer to memory block header */
pHead = pHdr(pUserData);
/* verify block type */
_ASSERTE(_BLOCK_TYPE_IS_VALID(pHead->nBlockUse));
_free_dbg( pUserData, pHead->nBlockUse );
__FINALLY
_munlock(_HEAP_LOCK); /* release other threads */
__END_TRY_FINALLY
return;
}
/*
free的實(shí)現(xiàn)
*/
#define free(p) _free_dbg(p, _NORMAL_BLOCK)
通過(guò)上述兩個(gè)全局函數(shù)的實(shí)現(xiàn)知道,operator new 實(shí)際也是通過(guò)malloc來(lái)申請(qǐng)空間,如果 malloc申請(qǐng)空間成功就直接返回,否則執(zhí)行用戶提供的空間不足應(yīng)對(duì)措施,如果用戶提供該措施就繼續(xù)申請(qǐng),否則就拋異常。operator delete 最終是通過(guò)free來(lái)釋放空間的。
五.malloc/free和new/delete的區(qū)別
malloc/free和new/delete的共同點(diǎn)是:
都是從堆上申請(qǐng)空間,并且需要用戶手動(dòng)釋放。
不同點(diǎn)是地方:
1. malloc和free是函數(shù),new和delete是操作符
2. malloc申請(qǐng)的空間不會(huì)初始化,new可以初始化
3. malloc申請(qǐng)空間時(shí),需要手動(dòng)計(jì)算空間大小并傳遞,new只需在其后跟上空間的類型即可, 如果是多個(gè)對(duì)象,[]中指定對(duì)象個(gè)數(shù)即可
4. malloc的返回值為void*, 在使用時(shí)必須強(qiáng)轉(zhuǎn),new不需要,因?yàn)閚ew后跟的是空間的類型
5. malloc申請(qǐng)空間失敗時(shí),返回的是NULL,因此使用時(shí)必須判空,new不需要,但是new需要捕獲異常
6. 申請(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ù)完成空間中資源的清理釋放。
補(bǔ):還有一個(gè)知識(shí)點(diǎn)就是定位new,是 C++ 提供的一種特殊的 new 運(yùn)算符,它允許在已經(jīng)分配的內(nèi)存地址上構(gòu)造對(duì)象。這個(gè)聯(lián)系內(nèi)存池在講解
總結(jié)
這次是對(duì)C++的內(nèi)存管理做了一個(gè)講解,下次開(kāi)始進(jìn)入string的學(xué)習(xí)
柚子快報(bào)激活碼778899分享:C++的內(nèi)存管理
參考閱讀
本文內(nèi)容根據(jù)網(wǎng)絡(luò)資料整理,出于傳遞更多信息之目的,不代表金鑰匙跨境贊同其觀點(diǎn)和立場(chǎng)。
轉(zhuǎn)載請(qǐng)注明,如有侵權(quán),聯(lián)系刪除。