詳解C++動(dòng)態(tài)內(nèi)存管理
1.c的動(dòng)態(tài)內(nèi)存管理
c語(yǔ)言的動(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)存申請(qǐng)函數(shù),不同點(diǎn)是:
- malloc 和calloc 的參數(shù)不同,前者是申請(qǐng)的字節(jié)大小,后者為一個(gè)類型的大小和個(gè)數(shù),
- malloc 不初始化,calloc 初始化
- malloc 為內(nèi)存分配一塊,calloc 分配n快
realloc是用來(lái)擴(kuò)容的函數(shù),就是你malloc或calloc空間不夠的時(shí)候,使用realloc來(lái)增加空間的。
注意:realloc擴(kuò)容方式有兩種,第一種就是malloc之后,后邊的內(nèi)存依然足夠擴(kuò)容,那么realloc就在之前空間的后面擴(kuò)容,如果不夠,則再找一塊內(nèi)存空間,將之前的數(shù)據(jù)拷貝到realloc里面,再擴(kuò)容。
2.C++動(dòng)態(tài)內(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)存管理。
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};//多次開(kāi)辟,初始化 int i = 0; for (i=0;i<3;i++) { cout << a3[i] << endl; } delete[] a3; return 0; }
注意:開(kāi)辟一個(gè)元素,delete不用加[],開(kāi)辟多個(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對(duì)于【自定義類型】除了開(kāi)空間還會(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)存申請(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 delete: 該函數(shù)最終是通過(guò)free來(lái)釋放空間的 */ 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)釋放空間的。
2.4 new 和 delete實(shí)現(xiàn)原理
- 內(nèi)置類型和malloc基本一樣,不會(huì)有太大差別。不同的地方是:new/delete申請(qǐng)和釋放的是單個(gè)元素的空間,new[]和delete[]申請(qǐng)的是連續(xù)空間,而且new在申請(qǐng)空間失敗時(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)是:都是從堆上申請(qǐng)空間,并且需要用戶手動(dòng)釋放。不同的地方是:
- 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ù)完成空間中資源的清理。
以上就是詳解C++動(dòng)態(tài)內(nèi)存管理的詳細(xì)內(nèi)容,更多關(guān)于C++動(dòng)態(tài)內(nèi)存管理的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
- C++ 多態(tài)性虛函數(shù)和動(dòng)態(tài)綁定學(xué)習(xí)筆記
- 關(guān)于C++虛函數(shù)與靜態(tài)、動(dòng)態(tài)綁定的問(wèn)題
- C++實(shí)現(xiàn)動(dòng)態(tài)綁定代碼分享
- 深入理解C++的動(dòng)態(tài)綁定與靜態(tài)綁定的應(yīng)用詳解
- C++內(nèi)存管理面經(jīng)
- 詳解C++中動(dòng)態(tài)內(nèi)存管理和泛型編程
- C++圖文并茂分析講解內(nèi)存管理
- 一文詳解C++中動(dòng)態(tài)內(nèi)存管理
- C語(yǔ)言與C++中內(nèi)存管理詳解
- 一起來(lái)學(xué)習(xí)C++的動(dòng)態(tài)內(nèi)存管理
- C++中動(dòng)態(tài)綁定和內(nèi)存管理的實(shí)現(xiàn)
相關(guān)文章
一些語(yǔ)言的按行讀取文件的代碼實(shí)現(xiàn)小結(jié)
這篇文章主要介紹了一些語(yǔ)言的按行讀取文件的代碼實(shí)現(xiàn)小結(jié),這里羅列了Java和C語(yǔ)言和C++以及PHP的實(shí)現(xiàn)需要的朋友可以參考下2015-08-08Qt使用事件與定時(shí)器實(shí)現(xiàn)字幕滾動(dòng)效果
我們經(jīng)常能夠在外面看到那種滾動(dòng)字幕,那么本文就拿Qt來(lái)做一個(gè)吧,本文將使用事件與定時(shí)器實(shí)現(xiàn)字幕滾動(dòng)的效果,感興趣的小伙伴可以了解一下2023-06-06C語(yǔ)言實(shí)現(xiàn)Flappy Bird小游戲
這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言實(shí)現(xiàn)Flappy Bird小游戲,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-12-12C++中實(shí)現(xiàn)矩陣的加法和乘法實(shí)例
這篇文章主要介紹了C++中實(shí)現(xiàn)矩陣的加法和乘法實(shí)例的相關(guān)資料,需要的朋友可以參考下2017-03-03C語(yǔ)言實(shí)現(xiàn)進(jìn)制轉(zhuǎn)換函數(shù)的實(shí)例詳解
這篇文章主要介紹了C語(yǔ)言實(shí)現(xiàn)進(jìn)制轉(zhuǎn)換函數(shù)的實(shí)例詳解的相關(guān)資料,這里提供實(shí)現(xiàn)實(shí)例幫助大家實(shí)現(xiàn)改功能,需要的朋友可以參考下2017-08-08C++ Custom Control控件向父窗體發(fā)送對(duì)應(yīng)的消息
這篇文章主要介紹了C++ Custom Control控件向父窗體發(fā)送對(duì)應(yīng)的消息的相關(guān)資料,需要的朋友可以參考下2015-06-06C++ 中使用不同平臺(tái)的時(shí)間函數(shù)及對(duì)比分析
在C++ 編程中,時(shí)間函數(shù)的選擇對(duì)于性能測(cè)量、任務(wù)調(diào)度和時(shí)間戳記錄至關(guān)重要,本文將介紹在 C++ 中常用的時(shí)間函數(shù),并比較它們?cè)诓煌脚_(tái)上的應(yīng)用和效果,感興趣的朋友跟隨小編一起看看吧2024-06-06C++實(shí)現(xiàn)一維向量旋轉(zhuǎn)算法
這篇文章主要介紹了C++實(shí)現(xiàn)一維向量旋轉(zhuǎn)算法,非常實(shí)用的經(jīng)典算法,需要的朋友可以參考下2014-08-08C語(yǔ)言結(jié)構(gòu)體簡(jiǎn)單入門講解
這篇文章主要介紹了C語(yǔ)言結(jié)構(gòu)體簡(jiǎn)單入門講解,本文講述了結(jié)構(gòu)體的基本定義和操作,講解了幾個(gè)比較實(shí)用的函數(shù)和案例,希望對(duì)你有所幫助2021-06-06