網(wǎng)站首頁(yè) 編程語(yǔ)言 正文
可執(zhí)行程序的虛擬地址空間
- 內(nèi)核:存放操作系統(tǒng)
- 棧區(qū):函數(shù)的形參,非靜態(tài)的局部變量,函數(shù)現(xiàn)場(chǎng) 保護(hù)數(shù)據(jù)等等,棧是向下增長(zhǎng)的。
- 共享庫(kù)的內(nèi)存映射區(qū)域:用于裝載一個(gè)共享的動(dòng)態(tài)內(nèi)存庫(kù)。用戶可使用系統(tǒng)接口創(chuàng)建共享內(nèi)存,做進(jìn)程間通信。
- 堆區(qū):用于程序運(yùn)行時(shí)動(dòng)態(tài)內(nèi)存分配,堆是可以上增長(zhǎng)的。
- 數(shù)據(jù):存儲(chǔ)全局?jǐn)?shù)據(jù)和靜態(tài)數(shù)據(jù),分為.bss和.data 。
- 代碼:可執(zhí)行的程序(機(jī)器指令)和常量數(shù)據(jù)。
1.new的運(yùn)算符用法(關(guān)鍵字)
int* p= new int(10);
這里的new的用法是當(dāng)作運(yùn)算符的用法,該用法一共有四個(gè)步驟:
- 計(jì)算類(lèi)型
- 申請(qǐng)一個(gè)空間(因?yàn)閚ew的底層是malloc)
- 將所取得的空間初始化
- 將申請(qǐng)到的地址返回
2.new的函數(shù)用法
new當(dāng)作函數(shù)用法使用的是時(shí)候,類(lèi)似malloc,都是申請(qǐng)一個(gè)空間,區(qū)別在于,返回值不同;當(dāng)空間不足時(shí)malloc會(huì)返回一個(gè)“nullptr”,operator new會(huì)返回一個(gè)throw_bad的異常。
當(dāng)我們加入一個(gè)nothrow后:
這樣申請(qǐng)錯(cuò)誤后,我們返回的是空指針。
對(duì)于malloc我們不可以進(jìn)行初始化,new也不可以初始化。
所以當(dāng)new作為函數(shù)時(shí)就相當(dāng)于malloc。
3.定位new
定位new用法與構(gòu)造new十分相似,是在已經(jīng)確定的空間當(dāng)中,構(gòu)造一個(gè)對(duì)象,并將該對(duì)象放置到聲明的空間當(dāng)中。
int main()
{
int n = 10;
int* ipa = (int*)ma11oc(sizeof(int));
int* ipb = (int*) : :operator new(sizeof(int) * n);
new(ipa) int(20);
new(ipb) int[]{ 1,2,3,4,5,6,7,8,9 };
free(ipa);
: :operator delete(ipb);
return 0;
}
不需要開(kāi)辟相應(yīng)的空間 合法空間即可 給出某個(gè)地址 即可根據(jù)要求進(jìn)行相應(yīng)操作。
4.new創(chuàng)建對(duì)象
new創(chuàng)建對(duì)象特點(diǎn):
- new創(chuàng)建對(duì)象需要指針接收,一處初始化,多處使用。
- new創(chuàng)建對(duì)象使用完需delete銷(xiāo)毀。
- new創(chuàng)建對(duì)象直接使用堆空間,而局部不用new定義對(duì)象則使用棧空間。
- new對(duì)象指針用途廣泛,比如作為函數(shù)返回值、函數(shù)參數(shù)等。
- 頻繁調(diào)用場(chǎng)合并不適合new,就像new申請(qǐng)和釋放內(nèi)存一樣。
new創(chuàng)建對(duì)象例子:
CTest* pTest = new CTest();
delete pTest;
pTest用來(lái)接收對(duì)象指針。
不用new,直接使用類(lèi)定義申明:
CTest mTest;
此種創(chuàng)建方式,使用完后不需要手動(dòng)釋放,該類(lèi)析構(gòu)函數(shù)會(huì)自動(dòng)執(zhí)行。
而new申請(qǐng)的對(duì)象,則只有調(diào)用到delete時(shí)再會(huì)執(zhí)行析構(gòu)函數(shù),如果程序退出而沒(méi)有執(zhí)行delete則會(huì)造成內(nèi)存泄漏。
C Test* pTest = NULL;
但使用普通方式創(chuàng)建的類(lèi)對(duì)象,在創(chuàng)建之初就已經(jīng)分配了內(nèi)存空間。
這類(lèi)指針,如果未經(jīng)過(guò)對(duì)象初始化,則不需要delete釋放。
5.delete
delete運(yùn)算符使用的一般格式為
delete [ ]指針變量
例如要撤銷(xiāo)上面用new開(kāi)辟的空間用:
delete p;
如果我們用“new char[10];”開(kāi)辟的字符數(shù)組空間,把new返回的指針賦給了指針變量pt,則應(yīng)該用以下形式的delete運(yùn)算符撤銷(xiāo)該空間:
delete [] pt;
一般來(lái)說(shuō)delete與new需要配對(duì)使用。
6.對(duì)于內(nèi)置類(lèi)型new/delete/malloc/free可以混用
- new/delete是C++中的運(yùn)算符。malloc / free是函數(shù)。
- malloc申請(qǐng)內(nèi)存空間時(shí),手動(dòng)計(jì)算所需大小,new只需類(lèi)型名,自動(dòng)計(jì)算大小;
- malloc申請(qǐng)的內(nèi)存空間不會(huì)初始化,new可以初始化;
- malloc的返回值為void*,接收時(shí)必須強(qiáng)轉(zhuǎn),new不需要;
- malloc申請(qǐng)內(nèi)存空間失敗時(shí),返回的是NULL,使用時(shí)必須判空;new申請(qǐng)內(nèi)存空間失敗時(shí)返回異常
7.使用注意事項(xiàng)
動(dòng)態(tài)分配失敗,則返回一個(gè)空指針(NULL),表示發(fā)生了異常,堆資源不足,分配失敗。
指針刪除與堆空間釋放。刪除一個(gè)指針p(delete p;)實(shí)際意思是刪除了p所指的目標(biāo)(變量或?qū)ο蟮龋尫帕怂嫉亩芽臻g,而不是刪除p本身(指針p本身并沒(méi)有撤銷(xiāo),它自己仍然存在,該指針?biāo)純?nèi)存空間并未釋放),釋放堆空間后,p成了空指針。
內(nèi)存泄漏(memory leak)和重復(fù)釋放。new與delete 是配對(duì)使用的, delete只能釋放堆空間。如果new返回的指針值丟失,則所分配的堆空間無(wú)法回收,稱(chēng)內(nèi)存泄漏,同一空間重復(fù)釋放也是危險(xiǎn)的,因?yàn)樵摽臻g可能已另分配,所以必須妥善保存new返回的指針,以保證不發(fā)生內(nèi)存泄漏,也必須保證不會(huì)重復(fù)釋放堆內(nèi)存空間。
動(dòng)態(tài)分配的變量或?qū)ο蟮纳凇N覀円卜Q(chēng)堆空間為自由空間(free store),但必須記住釋放該對(duì)象所占堆空間,并只能釋放一次,在函數(shù)內(nèi)建立,而在函數(shù)外釋放,往往會(huì)出錯(cuò)。
要訪問(wèn)new所開(kāi)辟的結(jié)構(gòu)體空間,無(wú)法直接通過(guò)變量名進(jìn)行,只能通過(guò)賦值的指針進(jìn)行訪問(wèn)。
用new和delete可以動(dòng)態(tài)開(kāi)辟和撤銷(xiāo)地址空間。在編程序時(shí),若用完一個(gè)變量(一般是暫時(shí)存儲(chǔ)的數(shù)據(jù)),下次需要再用,但卻又想省去重新初始化的功夫,可以在每次開(kāi)始使用時(shí)開(kāi)辟一個(gè)空間,在用完后撤銷(xiāo)它。
原文鏈接:https://blog.csdn.net/weixin_56935264/article/details/124858025
相關(guān)推薦
- 2022-08-21 Android貝塞爾曲線實(shí)現(xiàn)加入購(gòu)物車(chē)拋物線動(dòng)畫(huà)_Android
- 2022-10-22 Android?Choreographer源碼詳細(xì)分析_Android
- 2022-09-25 服務(wù)器ftp上傳失敗的原因有什么
- 2022-10-22 C#抽象類(lèi)的用法介紹_實(shí)用技巧
- 2022-03-31 C#算法之羅馬數(shù)字轉(zhuǎn)整數(shù)_C#教程
- 2022-07-26 讓一個(gè)有寬高的盒子垂直水平居中
- 2023-10-17 常用的utlis封裝
- 2022-10-20 Go通過(guò)不變性優(yōu)化程序詳解_Golang
- 最近更新
-
- window11 系統(tǒng)安裝 yarn
- 超詳細(xì)win安裝深度學(xué)習(xí)環(huán)境2025年最新版(
- Linux 中運(yùn)行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲(chǔ)小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎(chǔ)操作-- 運(yùn)算符,流程控制 Flo
- 1. Int 和Integer 的區(qū)別,Jav
- spring @retryable不生效的一種
- Spring Security之認(rèn)證信息的處理
- Spring Security之認(rèn)證過(guò)濾器
- Spring Security概述快速入門(mén)
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權(quán)
- redisson分布式鎖中waittime的設(shè)
- maven:解決release錯(cuò)誤:Artif
- restTemplate使用總結(jié)
- Spring Security之安全異常處理
- MybatisPlus優(yōu)雅實(shí)現(xiàn)加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務(wù)發(fā)現(xiàn)-Nac
- Spring Security之基于HttpR
- Redis 底層數(shù)據(jù)結(jié)構(gòu)-簡(jiǎn)單動(dòng)態(tài)字符串(SD
- arthas操作spring被代理目標(biāo)對(duì)象命令
- Spring中的單例模式應(yīng)用詳解
- 聊聊消息隊(duì)列,發(fā)送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠(yuǎn)程分支