詳解C++動(dòng)態(tài)內(nèi)存管理
1.c的動(dòng)態(tài)內(nèi)存管理
c語言的動(dòng)態(tài)內(nèi)存管理使用的函數(shù)為malloc/calloc/realloc/free
1.1 malloc/calloc/realloc
void Test ()
{
int* p1 = (int*) malloc(sizeof(int));
free(p1);
// 1.malloc/calloc/realloc的區(qū)別是什么?
int* p2 = (int*)calloc(4, sizeof (int));
int* p3 = (int*)realloc(p2, sizeof(int)*10);
// 這里需要free(p2)嗎?
free(p3 );
}malloc 和 calloc 都是動(dòng)態(tài)內(nèi)存申請函數(shù),不同點(diǎn)是:
- malloc 和calloc 的參數(shù)不同,前者是申請的字節(jié)大小,后者為一個(gè)類型的大小和個(gè)數(shù),
- malloc 不初始化,calloc 初始化
- malloc 為內(nèi)存分配一塊,calloc 分配n快
realloc是用來擴(kuò)容的函數(shù),就是你malloc或calloc空間不夠的時(shí)候,使用realloc來增加空間的。
注意:realloc擴(kuò)容方式有兩種,第一種就是malloc之后,后邊的內(nèi)存依然足夠擴(kuò)容,那么realloc就在之前空間的后面擴(kuò)容,如果不夠,則再找一塊內(nèi)存空間,將之前的數(shù)據(jù)拷貝到realloc里面,再擴(kuò)容。
2.C++動(dòng)態(tài)內(nèi)存管理
C語言內(nèi)存管理方式在C++中可以繼續(xù)使用,但有些地方就無能為力,而且使用起來比較麻煩,因
此C++又提出了自己的內(nèi)存管理方式:通過new和delete操作符進(jìn)行動(dòng)態(tài)內(nèi)存管理。
2.1 new/delete操作內(nèi)置類型
int main()
{
//text1();
int* a1 = new int;//不初始化
cout << *a1 << endl;
delete a1;
int* a2 = new int(1);//初始化為1
cout << *a2 << endl;
delete a2;
int* a3 = new int[3]{1,2,3};//多次開辟,初始化
int i = 0;
for (i=0;i<3;i++)
{
cout << a3[i] << endl;
}
delete[] a3;
return 0;
}注意:開辟一個(gè)元素,delete不用加[],開辟多個(gè)元素,delete一定要加[],不然會(huì)導(dǎo)致出現(xiàn)bug。
2.2 new/delete操作自定義類型
class sss
{
public:
sss(int a=0,int b=0)
:_a(a)
,_b(b)
{
;
}
~sss()
{
_a = 0;
_b = 0;
}
private:
int _a;
int _b;
};
int main()
{
//使用new
sss* s1 = new sss[2]{ {1,1},{2,2} };
delete[] s1;
//使用malloc
sss* s2 = (sss*)malloc(sizeof(sss)*2);
free(s2);
return 0;
}注意:new/delete 和 malloc/free最大區(qū)別是 new/delete對于【自定義類型】除了開空間還會(huì)調(diào)用構(gòu)造函數(shù)和析構(gòu)函數(shù)。且malloc不能初始化,new可以初始化,這是兩者最大的區(qū)別。
2.3 new底層原理
new和delete是用戶進(jìn)行動(dòng)態(tài)內(nèi)存申請和釋放的操作符,operator new 和operator delete是系統(tǒng)提供的全局函數(shù),new在底層調(diào)用operator new全局函數(shù)來申請空間,delete在底層通過operator delete全局函數(shù)來釋放空間。
底層代碼:
/*
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的實(shí)現(xiàn)
*/
#define free(p) _free_dbg(p, _NORMAL_BLOCK)通過上述兩個(gè)全局函數(shù)的實(shí)現(xiàn)知道,operator new 實(shí)際也是通過malloc來申請空間,如果malloc申請空間成功就直接返回,否則執(zhí)行用戶提供的空間不足應(yīng)對措施,如果用戶提供該措施就繼續(xù)申請,否則就拋異常。operator delete 最終是通過free來釋放空間的。
2.4 new 和 delete實(shí)現(xiàn)原理
- 內(nèi)置類型和malloc基本一樣,不會(huì)有太大差別。不同的地方是:new/delete申請和釋放的是單個(gè)元素的空間,new[]和delete[]申請的是連續(xù)空間,而且new在申請空間失敗時(shí)會(huì)拋異常,malloc會(huì)返回NULL。
- 自定義類型會(huì)調(diào)用構(gòu)造函數(shù)和析構(gòu)函數(shù),malloc不會(huì)調(diào)用。
3.malloc/free和new/delete的區(qū)別
malloc/free和new/delete的共同點(diǎn)是:都是從堆上申請空間,并且需要用戶手動(dòng)釋放。不同的地方是:
- 1. malloc和free是函數(shù),new和delete是操作符
- 2. malloc申請的空間不會(huì)初始化,new可以初始化
- 3. malloc申請空間時(shí),需要手動(dòng)計(jì)算空間大小并傳遞,new只需在其后跟上空間的類型即可,如果是多個(gè)對象,[]中指定對象個(gè)數(shù)即可
- 4. malloc的返回值為void*, 在使用時(shí)必須強(qiáng)轉(zhuǎn),new不需要,因?yàn)閚ew后跟的是空間的類型
- 5. malloc申請空間失敗時(shí),返回的是NULL,因此使用時(shí)必須判空,new不需要,但是new需要捕獲異常
- 6. 申請自定義類型對象時(shí),malloc/free只會(huì)開辟空間,不會(huì)調(diào)用構(gòu)造函數(shù)與析構(gòu)函數(shù),而new在申請空間后會(huì)調(diào)用構(gòu)造函數(shù)完成對象的初始化,delete在釋放空間前會(huì)調(diào)用析構(gòu)函數(shù)完成空間中資源的清理。
以上就是詳解C++動(dòng)態(tài)內(nèi)存管理的詳細(xì)內(nèi)容,更多關(guān)于C++動(dòng)態(tài)內(nèi)存管理的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
C++定時(shí)器實(shí)現(xiàn)和時(shí)間輪介紹
這篇文章主要介紹了C++定時(shí)器實(shí)現(xiàn)和時(shí)間輪介紹,定時(shí)器可以由很多種數(shù)據(jù)結(jié)構(gòu)實(shí)現(xiàn),比如最小堆、紅黑樹、跳表、甚至數(shù)組都可以,其本質(zhì)都是拿到最小時(shí)間的任務(wù),然后取出該任務(wù)并執(zhí)行,更多相關(guān)內(nèi)容介紹,需要的小伙伴可以參考一下2022-09-09
C++中sln,vcxproj,vcxproj.filters,lib,dll,exe的含義說明
這篇文章主要介紹了C++中sln,vcxproj,vcxproj.filters,lib,dll,exe的含義說明,具有很好的參考價(jià)值,希望對大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-05-05
用C++實(shí)現(xiàn)strcpy(),返回一個(gè)char*類型的深入分析
本篇文章是對用C++實(shí)現(xiàn)strcpy(),返回一個(gè)char*類型進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下2013-05-05
select函數(shù)實(shí)現(xiàn)高性能IO多路訪問的關(guān)鍵示例深入解析
這篇文章主要為大家介紹了select函數(shù)實(shí)現(xiàn)高性能IO多路訪問的關(guān)鍵示例深入解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-09-09

