目錄
??前言??
?? C/C++中內(nèi)存分布
?? new 和 delete的使用
?? new 和 delete的優(yōu)點
?? new 和 delete的原理
??? operator new 和 operator delete函數(shù)
??? 內(nèi)置類型
??? 自定義類型
?? 內(nèi)存泄漏
?? 總結(jié)
??前言??
? ? ? ? 歡迎收看本期【C++雜貨鋪】,本期內(nèi)容講解C++內(nèi)存管理。包含了C++中內(nèi)存分布情況,如何進行內(nèi)存管理,使用new和delete操作符開辟/釋放空間等,此外將介紹C++中new 和 delete的優(yōu)點和原理。
? ? ? ? 此外,本期內(nèi)容可能會涉及到類和對象的部分概念,如果你還不是很了解,可以快速閱覽以下文章:
【C++雜貨鋪】詳解類和對象 [上]-CSDN博客
【C++雜貨鋪】詳解類和對象 [中]-CSDN博客
【C++雜貨鋪】詳解類和對象 [下]-CSDN博客
?? C/C++中內(nèi)存分布
? ? ? ? 程序運行會被加載到內(nèi)存,程序的代碼和數(shù)據(jù)則會在內(nèi)存中存儲在不同地方,通過內(nèi)存地址進行訪問。
? ? ? ? 內(nèi)存地址是計算機中用來標識存儲單元位置的一個唯一的數(shù)字。在計算機中,每個存儲單元都有一個唯一的地址,通過這些地址可以訪問和操作存儲器中的數(shù)據(jù)。內(nèi)存地址通常用十六進制表示。
? ? ? ? 為了方便管理不同的類型的數(shù)據(jù),如全局變量和局部變量,就會在內(nèi)存中劃分出不同區(qū)域。
當(dāng)然這只是簡單的了解一下內(nèi)存分布,如果你學(xué)過操作系統(tǒng)的內(nèi)容,你就會知道,C/C++中的內(nèi)存概念其實都是虛擬內(nèi)存,不是真實的物理內(nèi)存。
? ? ? ? 上圖中,不同書籍可能會有偏差,如果只學(xué)過語言,只需要知道有棧,堆,數(shù)據(jù)段,代碼段即可。其中棧存放局部變量,形參等數(shù)據(jù),堆則是由程序員自己手動開辟,存放數(shù)據(jù)。
? ? ? ? 所以,堆區(qū)則是我們進行內(nèi)存管理的區(qū)域了。
?? new 和 delete的使用
? ? ? ? 學(xué)過C語言可能知道,想要在C語言中開辟內(nèi)存空間需要使用malloc函數(shù),釋放資源使用free函數(shù)。
? ? ? ? 下圖是malloc和free函數(shù)的使用示例。
開辟1個int類型數(shù)據(jù)的空間
int* pa = (int*)malloc(sizeof(int));
if(pa == NULL )
return 1;
free(pa);
開辟10個int類型數(shù)據(jù)的空間
int* parr = (int*)malloc(sizeof(int) * 10 );
釋放連續(xù)地址空間只需要給出首元素地址即可
free(parr);
? ? ? ? 我們可以看出使用malloc函數(shù)非常的不方便,例如只開辟空間,不能完成初始化;需要手動判斷內(nèi)存是否開辟成功。
? ? ? ? 此外,最重要的是,對于自定義類型,是需要構(gòu)造函數(shù)初始化,但是malloc開完空間后,不能調(diào)用構(gòu)造函數(shù)。
? ? ? ? 所以C++語言就引入了兩個操作符new 和 delete。
? ? ? ? 下圖是new 和 delete操作符的使用示例。
int* pa = new int;
delete pa;
int* parr = new int[10];
delete[] parr;
? ? ? ? 申請和釋放單個元素的空間,使用 new 和 delete 操作符,申請和釋放連續(xù)的空間,使用 new[] 和 delete[] ,注意:匹配起來使用
?? new 和 delete的優(yōu)點
? ? ? ? 上文中,我們已經(jīng)知道了new 和 delete 操作符的部分優(yōu)點:
1. 編譯器會自動檢查內(nèi)存空間是否成功開辟,如果失敗,則會拋異常。
2. 可以完成初始化的工作。對于自定義類型,會調(diào)用它的構(gòu)造函數(shù)和析構(gòu)函數(shù)。
int* pa = new int(1);
//如果是不完全初始化,后面會用0代替。
int* parr = new int(10){1,2,3,4,5};
?? new 和 delete的原理
? ? ? ? 以上我們簡單了解了new和delete操作符的基本使用,想要徹底掌握,我們就從底層了解new和delete的區(qū)別以及底層實現(xiàn)。
??? operator new 和 operator delete函數(shù)
? ? ? ? new 和 delete是用戶進行動態(tài)內(nèi)存申請和釋放的操作符,operator new 和 operator delete是系統(tǒng)提供的全局函數(shù),new在底層調(diào)用operator new全局函數(shù)來申請空間,delete底層通過operator delete全局函數(shù)來釋放空間。
/*
operator new:該函數(shù)實際通過malloc來申請空間,當(dāng)malloc申請空間成功時直接返回;申請空間
失敗,嘗試執(zhí)行空間不足應(yīng)對措施,如果改應(yīng)對措施用戶設(shè)置了,則繼續(xù)申請,否則拋異常。
*/
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
? ? ? ? // 如果申請內(nèi)存失敗了,這里會拋出bad_alloc 類型異常
? ? ? ? static const std::bad_alloc nomem;
? ? ? ? _RAISE(nomem);
? ? }
return (p);
}
/*
operator delete: 該函數(shù)最終是通過free來釋放空間的
*/
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的實現(xiàn)
*/
#define ? free(p) ? ? ? ? ? ? ? _free_dbg(p, _NORMAL_BLOCK)
? ? ? ? 通過兩個全局函數(shù)的實現(xiàn)就知道了,operator new 實際通過malloc來申請空間,如果malloc申請成功直接返回(原地擴容),否則執(zhí)行用戶提供的空間不足的措施(異地擴容),如果用戶提供改措施,則會繼續(xù)申請,否則拋異常。
?????????operator delete 最終通過free來釋放空間。
??? 內(nèi)置類型
? ? ? ? 如果申請的是內(nèi)置類型的空間(int , double,指針...),new和malloc ,delete和free基本類似,不同之處在于:new 和 delete 是申請和釋放單個元素空間,new[]和delete[]申請的是連續(xù)空間,釋放連續(xù)的空間。而且new申請空間時會拋異常,malloc則會返回NULL。
??? 自定義類型
????????● new的原理
? ? ? ? 1. 調(diào)用operator new函數(shù)申請空間。
? ? ? ? 2. 在申請的空間上執(zhí)行構(gòu)造函數(shù),完成對象的構(gòu)造。
????????● delete的原理
? ? ? ? 1. 在空間上進行析構(gòu)函數(shù),完成對象資源的清理工作。
? ? ? ? 2. 調(diào)用operator delete函數(shù)釋放對象空間。
????????● new[ ]的原理?
? ? ? ? 1. 調(diào)用operator new[ ]函數(shù),在operator new[ ]中實際調(diào)用operator new函數(shù)完成?N個對象空間的申請。
? ? ? ? 2. 在申請空間上調(diào)用N次構(gòu)造函數(shù)。
????????● delete[ ]的原理
? ? ? ? 1. 在釋放對象的空間上進行N次析構(gòu)函數(shù),完成N個對象中資源的清理。
? ? ? ? 2. 調(diào)用operator delete[ ]釋放資源,實際在operator delete[ ]中調(diào)用operator delete[ ]了釋放空間。
?? 內(nèi)存泄漏
????????
?? 總結(jié)
? ? ? ? 以上,就是本期【C++雜貨鋪】內(nèi)存管理的主要內(nèi)容了,主要介紹了new和delete操作符的使用,有點及其底層原理。
? ? ? ? 此外,簡單介紹了C/C++中內(nèi)存分布情況,以及內(nèi)存泄露的基本概念和危害。
? ? ? ? 如果感覺本期內(nèi)容對你有幫助,歡迎點贊,收藏,關(guān)注Thanks?(?ω?)?文章來源:http://www.zghlxwxcb.cn/news/detail-850714.html
文章來源地址http://www.zghlxwxcb.cn/news/detail-850714.html
到了這里,關(guān)于【C++雜貨鋪】內(nèi)管管理的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!