C++深入講解new與deleted關(guān)鍵字的使用
可執(zhí)行程序的虛擬地址空間
- 內(nèi)核:存放操作系統(tǒng)
- 棧區(qū):函數(shù)的形參,非靜態(tài)的局部變量,函數(shù)現(xiàn)場 保護(hù)數(shù)據(jù)等等,棧是向下增長的。
- 共享庫的內(nèi)存映射區(qū)域:用于裝載一個共享的動態(tài)內(nèi)存庫。用戶可使用系統(tǒng)接口創(chuàng)建共享內(nèi)存,做進(jìn)程間通信。
- 堆區(qū):用于程序運行時動態(tài)內(nèi)存分配,堆是可以上增長的。
- 數(shù)據(jù):存儲全局?jǐn)?shù)據(jù)和靜態(tài)數(shù)據(jù),分為.bss和.data 。
- 代碼:可執(zhí)行的程序(機(jī)器指令)和常量數(shù)據(jù)。
1.new的運算符用法(關(guān)鍵字)
int* p= new int(10);
這里的new的用法是當(dāng)作運算符的用法,該用法一共有四個步驟:
- 計算類型
- 申請一個空間(因為new的底層是malloc)
- 將所取得的空間初始化
- 將申請到的地址返回
2.new的函數(shù)用法
new當(dāng)作函數(shù)用法使用的是時候,類似malloc,都是申請一個空間,區(qū)別在于,返回值不同;當(dāng)空間不足時malloc會返回一個“nullptr”,operator new會返回一個throw_bad的異常。
當(dāng)我們加入一個nothrow后:
這樣申請錯誤后,我們返回的是空指針。
對于malloc我們不可以進(jìn)行初始化,new也不可以初始化。
所以當(dāng)new作為函數(shù)時就相當(dāng)于malloc。
3.定位new
定位new用法與構(gòu)造new十分相似,是在已經(jīng)確定的空間當(dāng)中,構(gòu)造一個對象,并將該對象放置到聲明的空間當(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; }
不需要開辟相應(yīng)的空間 合法空間即可 給出某個地址 即可根據(jù)要求進(jìn)行相應(yīng)操作。
4.new創(chuàng)建對象
new創(chuàng)建對象特點:
- new創(chuàng)建對象需要指針接收,一處初始化,多處使用。
- new創(chuàng)建對象使用完需delete銷毀。
- new創(chuàng)建對象直接使用堆空間,而局部不用new定義對象則使用??臻g。
- new對象指針用途廣泛,比如作為函數(shù)返回值、函數(shù)參數(shù)等。
- 頻繁調(diào)用場合并不適合new,就像new申請和釋放內(nèi)存一樣。
new創(chuàng)建對象例子:
CTest* pTest = new CTest(); delete pTest;
pTest用來接收對象指針。
不用new,直接使用類定義申明:
CTest mTest;
此種創(chuàng)建方式,使用完后不需要手動釋放,該類析構(gòu)函數(shù)會自動執(zhí)行。
而new申請的對象,則只有調(diào)用到delete時再會執(zhí)行析構(gòu)函數(shù),如果程序退出而沒有執(zhí)行delete則會造成內(nèi)存泄漏。
C Test* pTest = NULL;
但使用普通方式創(chuàng)建的類對象,在創(chuàng)建之初就已經(jīng)分配了內(nèi)存空間。
這類指針,如果未經(jīng)過對象初始化,則不需要delete釋放。
5.delete
delete運算符使用的一般格式為
delete [ ]指針變量
例如要撤銷上面用new開辟的空間用:
delete p;
如果我們用“new char[10];”開辟的字符數(shù)組空間,把new返回的指針賦給了指針變量pt,則應(yīng)該用以下形式的delete運算符撤銷該空間:
delete [] pt;
一般來說delete與new需要配對使用。
6.對于內(nèi)置類型new/delete/malloc/free可以混用
- new/delete是C++中的運算符。malloc / free是函數(shù)。
- malloc申請內(nèi)存空間時,手動計算所需大小,new只需類型名,自動計算大小;
- malloc申請的內(nèi)存空間不會初始化,new可以初始化;
- malloc的返回值為void*,接收時必須強(qiáng)轉(zhuǎn),new不需要;
- malloc申請內(nèi)存空間失敗時,返回的是NULL,使用時必須判空;new申請內(nèi)存空間失敗時返回異常
7.使用注意事項
動態(tài)分配失敗,則返回一個空指針(NULL),表示發(fā)生了異常,堆資源不足,分配失敗。
指針刪除與堆空間釋放。刪除一個指針p(delete p;)實際意思是刪除了p所指的目標(biāo)(變量或?qū)ο蟮龋?,釋放了它所占的堆空間,而不是刪除p本身(指針p本身并沒有撤銷,它自己仍然存在,該指針?biāo)純?nèi)存空間并未釋放),釋放堆空間后,p成了空指針。
內(nèi)存泄漏(memory leak)和重復(fù)釋放。new與delete 是配對使用的, delete只能釋放堆空間。如果new返回的指針值丟失,則所分配的堆空間無法回收,稱內(nèi)存泄漏,同一空間重復(fù)釋放也是危險的,因為該空間可能已另分配,所以必須妥善保存new返回的指針,以保證不發(fā)生內(nèi)存泄漏,也必須保證不會重復(fù)釋放堆內(nèi)存空間。
動態(tài)分配的變量或?qū)ο蟮纳?。我們也稱堆空間為自由空間(free store),但必須記住釋放該對象所占堆空間,并只能釋放一次,在函數(shù)內(nèi)建立,而在函數(shù)外釋放,往往會出錯。
要訪問new所開辟的結(jié)構(gòu)體空間,無法直接通過變量名進(jìn)行,只能通過賦值的指針進(jìn)行訪問。
用new和delete可以動態(tài)開辟和撤銷地址空間。在編程序時,若用完一個變量(一般是暫時存儲的數(shù)據(jù)),下次需要再用,但卻又想省去重新初始化的功夫,可以在每次開始使用時開辟一個空間,在用完后撤銷它。
到此這篇關(guān)于C++深入講解new與deleted關(guān)鍵字的使用的文章就介紹到這了,更多相關(guān)C++ new與deleted內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
在C/C++與Python之間實現(xiàn)通信的常見方法
在C/C++與Python之間實現(xiàn)通信的方式有很多,本文給大家介紹了一些常見的方法,文中通過代碼示例介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作有一定的幫助,需要的朋友可以參考下2023-12-12C++實現(xiàn)LeetCode(37.求解數(shù)獨)
這篇文章主要介紹了C++實現(xiàn)LeetCode(37.求解數(shù)獨),本篇文章通過簡要的案例,講解了該項技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下2021-07-07android studio創(chuàng)建C++項目的實現(xiàn)示例
本文主要介紹了android studio創(chuàng)建C++項目的實現(xiàn)示例,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2022-06-06Qt圖形圖像開發(fā)之曲線圖表模塊QChart庫讀取/設(shè)置X軸的顯示區(qū)間
這篇文章主要介紹了Qt圖形圖像開發(fā)之曲線圖表模塊QChart庫讀取/設(shè)置X軸的顯示區(qū)間,需要的朋友可以參考下2020-03-03C/C++ 中const關(guān)鍵字的用法小結(jié)
C++中的const關(guān)鍵字的用法非常靈活,而使用const將大大改善程序的健壯性。這篇文章主要介紹了C/C++ 中const關(guān)鍵字的用法,需要的朋友可以參考下2020-02-02