C++內(nèi)存管理看這一篇就夠了
1 內(nèi)存分布圖
注意:
1.向下生長(zhǎng):地址由高到低
2.向上生長(zhǎng):地址由低到高
3.棧又叫堆棧,非靜態(tài)局部變量/函數(shù)參數(shù)/返回值等等
4.堆用于程序運(yùn)行時(shí)動(dòng)態(tài)內(nèi)存分配
2 C語(yǔ)言和C++內(nèi)存分配實(shí)現(xiàn)
2.1 C語(yǔ)言實(shí)現(xiàn)
malloc函數(shù)
void *malloc(size_t size)
分配所需的內(nèi)存空間,單位是字節(jié),并返回一個(gè)指向它的指針。
int* ptr_int = (int*)malloc(4*sizeof(int));//開(kāi)辟空間 free(ptr_int);//釋放空間
calloc函數(shù)
void *calloc(size_t nitems, size_t size)
分配所需的內(nèi)存空間,并返回一個(gè)指向它的指針。nitems – 要被分配的元素個(gè)數(shù)。size – 元素的大小。malloc 和 calloc 之間的不同點(diǎn)是,malloc 不會(huì)設(shè)置內(nèi)存為零,而 calloc 會(huì)設(shè)置分配的內(nèi)存為零。
char* ptr_char = (char*)calloc(4, sizeof(char)); free(ptr_char);
realloc
void *realloc(void *ptr, size_t size)
嘗試重新調(diào)整之前調(diào)用 malloc 或 calloc 所分配的ptr 所指向的內(nèi)存塊的大小。ptr – 指針指向一個(gè)要重新分配內(nèi)存的內(nèi)存塊,該內(nèi)存塊之前是通過(guò)調(diào)用 malloc、calloc 或 realloc 進(jìn)行分配內(nèi)存的。如果為空指針,則會(huì)分配一個(gè)新的內(nèi)存塊,且函數(shù)返回一個(gè)指向它的指針。
size – 內(nèi)存塊的新的大小,以字節(jié)為單位。如果大小為 0,且 ptr 指向一個(gè)已存在的內(nèi)存塊,則 ptr 所指向的內(nèi)存塊會(huì)被釋放,并返回一個(gè)空指針。
int* ptr_int = (int*)malloc(4*sizeof(int)); char* ptr_char = (char*)calloc(4, sizeof(char)); int* ptr_int1 = (int*)realloc(ptr_int, 8 * sizeof(int)); char* ptr_char1 = (char*)realloc(ptr_char, 8 * sizeof(char));
2.2 C++實(shí)現(xiàn)
new和delete的實(shí)現(xiàn)原理
1 內(nèi)置類型
- 如果申請(qǐng)的是內(nèi)置類型的空間,new和malloc,delete和free基本類似,不同的地方是:new/delete申請(qǐng)和釋放的是單個(gè)元素的空間,new[]和delete[]申請(qǐng)的是連續(xù)空間,而且new在申請(qǐng)空間失敗時(shí)會(huì)拋異常,malloc會(huì)返回NULL。
2 自定義類型
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ì)象的空間
3 C語(yǔ)言和C++內(nèi)存管理區(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只需在其后跟上空間的類型即可
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ù)完成空間中資源的清理
4 內(nèi)存泄漏
什么是內(nèi)存泄漏:
內(nèi)存泄漏指因?yàn)槭韬龌蝈e(cuò)誤造成程序未能釋放已經(jīng)不再使用的內(nèi)存的情況。內(nèi)存泄漏并不是指內(nèi)存在物理上的消失,而是應(yīng)用程序分配某段內(nèi)存后,因?yàn)樵O(shè)計(jì)錯(cuò)誤,失去了對(duì)該段內(nèi)存的控制,因而造成了內(nèi)存的浪費(fèi)。
內(nèi)存泄漏的危害:長(zhǎng)期運(yùn)行的程序出現(xiàn)內(nèi)存泄漏,影響很大,如操作系統(tǒng)、后臺(tái)服務(wù)等等,出現(xiàn)內(nèi)存泄漏會(huì)導(dǎo)致響應(yīng)越來(lái)越慢,最終卡死。
堆內(nèi)存泄漏(Heap leak)
堆內(nèi)存指的是程序執(zhí)行中依據(jù)須要分配通過(guò)malloc / calloc / realloc / new等從堆中分配的一塊內(nèi)存,用完后必須通過(guò)調(diào)用相應(yīng)的 free或者delete 刪掉。假設(shè)程序的設(shè)計(jì)錯(cuò)誤導(dǎo)致這部分內(nèi)存沒(méi)有被釋放,那么以后這部分空間將無(wú)法再被使用,就會(huì)產(chǎn)生Heap Leak。
系統(tǒng)資源泄漏
指程序使用系統(tǒng)分配的資源,比方套接字、文件描述符、管道等沒(méi)有使用對(duì)應(yīng)的函數(shù)釋放掉,導(dǎo)致系統(tǒng)資源的浪費(fèi),嚴(yán)重可導(dǎo)致系統(tǒng)效能減少,系統(tǒng)執(zhí)行不穩(wěn)定。
總結(jié)
本篇文章就到這里了,希望能給你帶來(lái)幫助,也希望您能夠多多關(guān)注腳本之家的更多內(nèi)容!
相關(guān)文章
Java實(shí)現(xiàn)批量導(dǎo)入excel表格數(shù)據(jù)到數(shù)據(jù)庫(kù)中的方法
這篇文章主要介紹了Java實(shí)現(xiàn)批量導(dǎo)入excel表格數(shù)據(jù)到數(shù)據(jù)庫(kù)中的方法,結(jié)合實(shí)例形式詳細(xì)分析了java導(dǎo)入Excel數(shù)據(jù)到數(shù)據(jù)庫(kù)的具體步驟與相關(guān)操作技巧,需要的朋友可以參考下2017-10-10Java 根據(jù)網(wǎng)絡(luò)URL獲取該網(wǎng)頁(yè)上面所有的img標(biāo)簽并下載圖片
這篇文章主要介紹了Java 根據(jù)網(wǎng)絡(luò)URL獲取該網(wǎng)頁(yè)上面所有的img標(biāo)簽并下載圖片,幫助大家更好的理解和使用Java,感興趣的朋友可以了解下2020-11-11使用resty Quartz執(zhí)行定時(shí)任務(wù)的配置方法
這篇文章主要為大家介紹了使用resty?Quartz來(lái)執(zhí)行定時(shí)任務(wù)的配置方法,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步2022-03-03MVC頁(yè)面之間參數(shù)傳遞實(shí)現(xiàn)過(guò)程圖解
這篇文章主要介紹了MVC頁(yè)面之間參數(shù)傳遞實(shí)現(xiàn)過(guò)程圖解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-11-11m1 Mac設(shè)置多jdk版本并動(dòng)態(tài)切換的實(shí)現(xiàn)
本文主要介紹 Mac 下如何安裝 JDK 并且多版本如何切換,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-08-08詳解FileInputStream讀取文件數(shù)據(jù)的兩種方式
這篇文章主要介紹了詳解FileInputStream讀取文件數(shù)據(jù)的兩種方式,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-08-08java使用正則表達(dá)式判斷手機(jī)號(hào)的方法示例
這篇文章主要介紹了java使用正則表達(dá)式判斷手機(jī)號(hào)的方法,分析了手機(jī)號(hào)碼段的原理及java使用正則表達(dá)式針對(duì)手機(jī)號(hào)的匹配操作實(shí)現(xiàn)技巧,需要的朋友可以參考下2017-06-06