亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > C++ > 正文

淺談 C++ 中的 new/delete 和 new[]/delete[]

2019-11-06 06:11:14
字體:
供稿:網(wǎng)友

原始出處:http://www.cnblogs.com/hazir/p/new_and_delete.html

在 C++ 中,你也許經(jīng)常使用 new 和 delete 來動(dòng)態(tài)申請和釋放內(nèi)存,但你可曾想過以下問題呢?

new 和 delete 是函數(shù)嗎?new [] 和 delete [] 又是什么?什么時(shí)候用它們?你知道 Operator new 和 operator delete 嗎?為什么 new [] 出來的數(shù)組有時(shí)可以用 delete 釋放有時(shí)又不行?…

如果你對這些問題都有疑問的話,不妨看看我這篇文章。

new 和 delete 到底是什么?

如果找工作的同學(xué)看一些面試的書,我相信都會(huì)遇到這樣的題:sizeof 不是函數(shù),然后舉出一堆的理由來證明 sizeof 不是函數(shù)。在這里,和 sizeof 類似,new 和 delete 也不是函數(shù),它們都是 C++ 定義的關(guān)鍵字,通過特定的語法可以組成表達(dá)式。和 sizeof 不同的是,sizeof 在編譯時(shí)候就可以確定其返回值,new 和 delete 背后的機(jī)制則比較復(fù)雜。繼續(xù)往下之前,請你想想你認(rèn)為 new 應(yīng)該要做些什么?也許你第一反應(yīng)是,new 不就和 C 語言中的 malloc 函數(shù)一樣嘛,就用來動(dòng)態(tài)申請空間的。你答對了一半,看看下面語句:

string *ps = new string("hello world");

你就可以看出 new 和 malloc 還是有點(diǎn)不同的,malloc 申請完空間之后不會(huì)對內(nèi)存進(jìn)行必要的初始化,而 new 可以。所以 new exPRession 背后要做的事情不是你想象的那么簡單。在我用實(shí)例來解釋 new 背后的機(jī)制之前,你需要知道 operator new 和 operator delete 是什么玩意。

operator new 和 operator delete

這兩個(gè)其實(shí)是 C++ 語言標(biāo)準(zhǔn)庫的庫函數(shù),原型分別如下:

void *operator new(size_t);     //allocate an objectvoid *operator delete(void *);    //free an objectvoid *operator new[](size_t);     //allocate an arrayvoid *operator delete[](void *);    //free an array

后面兩個(gè)你可以先不看,后面再介紹。前面兩個(gè)均是 C++ 標(biāo)準(zhǔn)庫函數(shù),你可能會(huì)覺得這是函數(shù)嗎?請不要懷疑,這就是函數(shù)!C++ Primer 一書上說這不是重載 new 和 delete 表達(dá)式(如 operator= 就是重載 = 操作符),因?yàn)?new 和 delete 是不允許重載的。但我還沒搞清楚為什么要用 operator new 和 operator delete 來命名,比較費(fèi)解。我們只要知道它們的意思就可以了,這兩個(gè)函數(shù)和 C 語言中的 malloc 和 free 函數(shù)有點(diǎn)像了,都是用來申請和釋放內(nèi)存的,并且 operator new 申請內(nèi)存之后不對內(nèi)存進(jìn)行初始化,直接返回申請內(nèi)存的指針。

我們可以直接在我們的程序中使用這幾個(gè)函數(shù)。

new 和 delete 背后機(jī)制

知道上面兩個(gè)函數(shù)之后,我們用一個(gè)實(shí)例來解釋 new 和 delete 背后的機(jī)制:

我們不用簡單的 C++ 內(nèi)置類型來舉例,使用復(fù)雜一點(diǎn)的類類型,定義一個(gè)類 A:

class A{public:    A(int v) : var(v)    {        fopen_s(&file, "test", "r");    }    ~A()    {        fclose(file);    }private:    int var;    FILE *file;};

很簡單,類 A 中有兩個(gè)私有成員,有一個(gè)構(gòu)造函數(shù)和一個(gè)析構(gòu)函數(shù),構(gòu)造函數(shù)中初始化私有變量 var 以及打開一個(gè)文件,析構(gòu)函數(shù)關(guān)閉打開的文件。

我們使用

class A *pA = new A(10);

來創(chuàng)建一個(gè)類的對象,返回其指針 pA。如下圖所示 new 背后完成的工作:

簡單總結(jié)一下:

首先需要調(diào)用上面提到的 operator new 標(biāo)準(zhǔn)庫函數(shù),傳入的參數(shù)為 class A 的大小,這里為 8 個(gè)字節(jié),至于為什么是 8 個(gè)字節(jié),你可以看看《深入 C++ 對象模型》一書,這里不做多解釋。這樣函數(shù)返回的是分配內(nèi)存的起始地址,這里假設(shè)是 0x007da290。上面分配的內(nèi)存是未初始化的,也是未類型化的,第二步就在這一塊原始的內(nèi)存上對類對象進(jìn)行初始化,調(diào)用的是相應(yīng)的構(gòu)造函數(shù),這里是調(diào)用 A:A(10); 這個(gè)函數(shù),從圖中也可以看到對這塊申請的內(nèi)存進(jìn)行了初始化,var=10, file 指向打開的文件。最后一步就是返回新分配并構(gòu)造好的對象的指針,這里 pA 就指向 0x007da290 這塊內(nèi)存,pA 的類型為類 A 對象的指針。

所有這三步,你都可以通過反匯編找到相應(yīng)的匯編代碼,在這里我就不列出了。

好了,那么 delete 都干了什么呢?還是接著上面的例子,如果這時(shí)想釋放掉申請的類的對象怎么辦?當(dāng)然我們可以使用下面的語句來完成:

delete pA;

delete 所做的事情如下圖所示:

delete 就做了兩件事情:

調(diào)用 pA 指向?qū)ο蟮奈鰳?gòu)函數(shù),對打開的文件進(jìn)行關(guān)閉。通過上面提到的標(biāo)準(zhǔn)庫函數(shù) operator delete 來釋放該對象的內(nèi)存,傳入函數(shù)的參數(shù)為 pA 的值,也就是 0x007d290。

好了,解釋完了 new 和 delete 背后所做的事情了,是不是覺得也很簡單?不就多了一個(gè)構(gòu)造函數(shù)和析構(gòu)函數(shù)的調(diào)用嘛。

如何申請和釋放一個(gè)數(shù)組?

我們經(jīng)常要用到動(dòng)態(tài)分配一個(gè)數(shù)組,也許是這樣的:

string *psa = new string[10];      //array of 10 empty stringsint *pia = new int[10];           //array of 10 uninitialized ints

上面在申請一個(gè)數(shù)組時(shí)都用到了 new [] 這個(gè)表達(dá)式來完成,按照我們上面講到的 new 和 delete 知識,第一個(gè)數(shù)組是 string 類型,分配了保存對象的內(nèi)存空間之后,將調(diào)用 string 類型的默認(rèn)構(gòu)造函數(shù)依次初始化數(shù)組中每個(gè)元素;第二個(gè)是申請具有內(nèi)置類型的數(shù)組,分配了存儲 10 個(gè) int 對象的內(nèi)存空間,但并沒有初始化。

如果我們想釋放空間了,可以用下面兩條語句:

delete [] psa;delete [] pia;

都用到 delete [] 表達(dá)式,注意這地方的 [] 一般情況下不能漏掉!我們也可以想象這兩個(gè)語句分別干了什么:第一個(gè)對 10 個(gè) string 對象分別調(diào)用析構(gòu)函數(shù),然后再釋放掉為對象分配的所有內(nèi)存空間;第二個(gè)因?yàn)槭莾?nèi)置類型不存在析構(gòu)函數(shù),直接釋放為 10 個(gè) int 型分配的所有內(nèi)存空間。

這里對于第一種情況就有一個(gè)問題了:我們?nèi)绾沃?psa 指向?qū)ο蟮臄?shù)組的大小?怎么知道調(diào)用幾次析構(gòu)函數(shù)?

這個(gè)問題直接導(dǎo)致我們需要在 new [] 一個(gè)對象數(shù)組時(shí),需要保存數(shù)組的維度,C++ 的做法是在分配數(shù)組空間時(shí)多分配了 4 個(gè)字節(jié)的大小,專門保存數(shù)組的大小,在 delete [] 時(shí)就可以取出這個(gè)保存的數(shù),就知道了需要調(diào)用析構(gòu)函數(shù)多少次了。

還是用圖來說明比較清楚,我們定義了一個(gè)類 A,但不具體描述類的內(nèi)容,這個(gè)類中有顯示的構(gòu)造函數(shù)、析構(gòu)函數(shù)等。那么 當(dāng)我們調(diào)用

class A *pAa = new A[3];

時(shí)需要做的事情如下:

從這個(gè)圖中我們可以看到申請時(shí)在數(shù)組對象的上面還多分配了 4 個(gè)字節(jié)用來保存數(shù)組的大小,但是最終返回的是對象數(shù)組的指針,而不是所有分配空間的起始地址。

這樣的話,釋放就很簡單了:

delete []pAa;

這里要注意的兩點(diǎn)是:

調(diào)用析構(gòu)函數(shù)的次數(shù)是從數(shù)組對象指針前面的 4 個(gè)字節(jié)中取出;傳入 operator delete[] 函數(shù)的參數(shù)不是數(shù)組對象的指針 pAa,而是 pAa 的值減 4。

為什么 new/delete 、new []/delete[] 要配對使用?

其實(shí)說了這么多,還沒到我寫這篇文章的最原始意圖。從上面解釋的你應(yīng)該懂了 new/delete、new[]/delete[] 的工作原理了,因?yàn)樗鼈冎g有差別,所以需要配對使用。但偏偏問題不是這么簡單,這也是我遇到的問題,如下這段代碼:

int *pia = new int[10];delete []pia;

這肯定是沒問題的,但如果把 delete []pia; 換成 delete pia; 的話,會(huì)出問題嗎?

這就涉及到上面一節(jié)沒提到的問題了。上面我提到了在 new [] 時(shí)多分配 4 個(gè)字節(jié)的緣由,因?yàn)槲鰳?gòu)時(shí)需要知道數(shù)組的大小,但如果不調(diào)用析構(gòu)函數(shù)呢(如內(nèi)置類型,這里的 int 數(shù)組)?我們在 new [] 時(shí)就沒必要多分配那 4 個(gè)字節(jié), delete [] 時(shí)直接到第二步釋放為 int 數(shù)組分配的空間。如果這里使用 delete pia;那么將會(huì)調(diào)用 operator delete 函數(shù),傳入的參數(shù)是分配給數(shù)組的起始地址,所做的事情就是釋放掉這塊內(nèi)存空間。不存在問題的。

這里說的使用 new [] 用 delete 來釋放對象的提前是:對象的類型是內(nèi)置類型或者是無自定義的析構(gòu)函數(shù)的類類型!

我們看看如果是帶有自定義析構(gòu)函數(shù)的類類型,用 new [] 來創(chuàng)建類對象數(shù)組,而用 delete 來釋放會(huì)發(fā)生什么?用上面的例子來說明:

class A *pAa = new class A[3];delete pAa;

那么 delete pAa; 做了兩件事:

調(diào)用一次 pAa 指向的對象的析構(gòu)函數(shù);調(diào)用 operator delete(pAa); 釋放內(nèi)存。

顯然,這里只對數(shù)組的第一個(gè)類對象調(diào)用了析構(gòu)函數(shù),后面的兩個(gè)對象均沒調(diào)用析構(gòu)函數(shù),如果類對象中申請了大量的內(nèi)存需要在析構(gòu)函數(shù)中釋放,而你卻在銷毀數(shù)組對象時(shí)少調(diào)用了析構(gòu)函數(shù),這會(huì)造成內(nèi)存泄漏。

上面的問題你如果說沒關(guān)系的話,那么第二點(diǎn)就是致命的了!直接釋放 pAa 指向的內(nèi)存空間,這個(gè)總是會(huì)造成嚴(yán)重的段錯(cuò)誤,程序必然會(huì)奔潰!因?yàn)榉峙涞目臻g的起始地址是 pAa 指向的地方減去 4 個(gè)字節(jié)的地方。你應(yīng)該傳入?yún)?shù)設(shè)為那個(gè)地址!

同理,你可以分析如果使用 new 來分配,用 delete [] 來釋放會(huì)出現(xiàn)什么問題?是不是總會(huì)導(dǎo)致程序錯(cuò)誤?

總的來說,記住一點(diǎn)即可:new/delete、new[]/delete[] 要配套使用總是沒錯(cuò)的!

參考資料:

C++ Primer 第四版


發(fā)表評論 共有條評論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表

圖片精選

免费av成人在线| 99视频资源网| 韩日毛片在线观看| 亚洲最大激情中文字幕| 日本大片在线看黄a∨免费| 国内精品伊人久久| 婷婷成人综合| 日本免费在线视频观看| 在线碰免费视频在线观看| 丝袜美腿一区二区三区| 激情综合网天天干| 欧美精品在线视频| 不卡av免费在线观看| 丝袜足脚交91精品| 亚洲裸体视频| 91成人在线视频观看| 欧美日韩中文在线视频| 日韩乱码在线观看| 国产传媒一区二区三区| 福利在线观看| 久久99精品国产91久久来源| 手机免费看av网站| 日本免费精品| 国产亚洲欧美另类一区二区三区| h色网站在线观看| 色94色欧美sute亚洲13| 五月婷婷六月丁香综合| 日本午夜视频在线观看| 国产很黄免费观看久久| 粉嫩虎白女毛片人体| 日本福利视频导航| 免费在线看黄色片| 91国偷自产一区二区三区成为亚洲经典| 亚洲精品国产精品国自产| 日韩人妻精品一区二区三区| 天堂在线资源8| 日本边添边摸边做边爱的第三级| 性一爱一乱一交一视频| 中文字幕不卡| 日本午夜精品久久久| 自拍在线播放| 一级特级黄色片| 亚洲一区二区精品在线| 精品国产一区二区三区久久| 国产精品人妖ts系列视频| 免费成人美女女| 黑人性生活视频| 亚洲中无吗在线| 色偷偷男人天堂| 成人国产精品入口免费视频| 久久久久99精品国产片| dy888夜精品国产专区| 亚洲无玛一区| 国产欧美精品一区二区色综合朱莉| 国产高清精品二区| 精品亚洲男同gayvideo网站| jizz性欧美10| 91精品国产色综合久久不卡粉嫩| 91精品国产黑色紧身裤美女| 久久免费激情视频| 亚洲综合伊人久久大杳蕉| 亚洲国产高潮在线观看| 亚洲国产精品自拍视频| 精品在线手机视频| 国产精品性做久久久久久| 天天操天天干天天做| 亚洲国产电影在线观看| 欧美一卡二卡三卡四卡| av电影天堂一区二区在线观看| 毛片基地一级大毛片| 偷拍中文亚洲欧美动漫| 欧美午夜理伦三级在线观看| 黄色网址大全在线观看| 亚洲影院色在线观看免费| 国产xxxxxx| 久久精品小视频| 国内精品视频在线播放| 成人不卡免费视频| 日韩欧美大片在线观看| 亚洲经典一区二区| 免费动漫网站在线观看| 蜜臂av日日欢夜夜爽一区| 青草草在线视频| 欧美一级免费| 狠狠色狠狠色综合系列| 欧美精品一区在线发布| 成年人黄色在线观看| 欧美精品第一区| 凹凸国产熟女精品视频| 视频一区中文字幕精品| 曰本女人与公拘交酡| 国产自产高清不卡| 亚洲一区在线观看免费| 三级一区二区三区| 亚洲a一区二区| 午夜av免费看| 亚洲一区二区三区加勒比| www欧美日韩| 亚洲精品免费电影| 亚洲欧洲成人在线| 99精品视频在线看| 区一区二日本| 青青国产在线观看| 欧美孕妇与黑人孕交| 欧美aⅴ一区二区三区视频| 2019亚洲日韩新视频| 九九在线高清精品视频| 欧美日韩成人免费| 极品魔鬼身材女神啪啪精品| 男人天堂免费视频| 欧美亚洲一二三区| 香蕉久久aⅴ一区二区三区| 免费的国产精品| 国产淫片av片久久久久久| 国产在线高清理伦片a| 亚洲成人手机在线观看| √天堂中文在线| 精品亚洲欧美日韩| 日韩欧美电影在线| 少妇一级淫片日本| 中国黄色a级片| 欧美俄罗斯乱妇| 日本91av在线播放| 自拍视频国产精品| 日韩欧美一区免费| 亚洲福利精品视频| 国产精品午夜影院| 欧美日本在线一区| julia京香一区二区三区| 国产成人精品免费看在线播放| 91精品国产综合久久婷婷香蕉| 成年永久一区二区三区免费视频| 亚洲精品乱码久久久久| 欧美精品videossex少妇| 国产精品国产三级国产aⅴ原创| 欧美a级网站| 91丝袜美腿高跟国产极品老师| 亚洲精品高清在线观看| 全部孕妇毛片丰满孕妇孕交| 国产精品wwwwww| 在线看黄的网站| 九九久久久久久久久激情| 国产午夜亚洲精品不卡| 精品国产亚洲一区二区三区大结局| 欧美激情欧美激情| 日韩中文字幕电影| 视频在线观看91| 国产精品 欧美在线| 国产一区在线电影| 在线观看免费小视频| www.av视频| 亚洲伊人第一页| 亚洲一区二区三区四区电影| 天天噜天天色| www婷婷av久久久影片| 欧美人与拘性视交免费看| 这里只有精品久久| 日本一二三区在线观看| 色av性av丰满av| 日韩久久久久久久| 黄色国产网站在线观看| www青青草原| 亚洲激情专区| 天天骑夜夜操| 麻豆免费在线观看视频| 爽爽影院免费观看视频| 欧美有码在线| 国产一区二区女| 欧美不卡高清一区二区三区| 91嫩草在线视频| 国产精选在线观看| 亚洲高清不卡一区| www.玖玖玖| 影院欧美亚洲| 国产成人av| 欧美日韩午夜在线视频| 国产 日韩 欧美一区| jizzjizzwww| 成人免费看片视频| 久久国产精品99久久久久久丝袜| 99久久夜色精品国产网站| 中文字幕精品无码一区二区| 天堂在线一区二区三区| 国产精品久久久久久久妇| 国产色婷婷国产综合在线理论片a| www国产亚洲精品久久网站| 欧美激情一区二区久久久| 亚洲精品免费一区二区三区| 久久国产精品久久久| 视频在线观看你懂的| 国产一级二级三级视频| 国产农村妇女毛片精品久久莱园子| 精品精品国产高清一毛片一天堂| 黄色激情网站| 亚洲电影免费观看高清完整版在线| 欧美福利视频在线观看| 国产日韩欧美不卡在线| 天堂在线视频观看| 欧美热在线视频精品999| 看欧美日韩国产| 欧美激情第二页| 国产日本久久| 国产精品人人做人人爽| 欧美日韩国产丝袜美女| 波多野结衣一区| 一区二区在线观看免费视频播放| 国产久一道中文一区| 91精品99| 日韩在线影视| 精品国产精品国产偷麻豆| 大陆精大陆国产国语精品| 日本不卡一区二区三区四区| 夜夜嗨一区二区| 欧美激情第1页| 精品国产区在线| 2019年中文字幕| 国产精品30p| 免费福利在线| 欧美性bbwbbwbbwhd| 亚洲人成绝费网站色www| 日韩黄色视屏| 9色在线视频网站| 国产v片免费观看| 天天爱天天干天天操| 久久国产柳州莫菁门| 亚洲日本伊人| 亚洲精品中文在线| 欧美一区二区视频免费观看| 春暖花开成人亚洲区| 国产欧美日韩最新| 成人av小说网| 我要看一级黄色录像| 国产av一区二区三区传媒| 国产偷国产偷亚洲高清97cao| www.激情网| 国产成人手机高清在线观看网站| 肉肉视频在线观看| eeuss影院www免费视频| 精品久久久久久无码中文野结衣| 午夜a成v人精品| 午夜影院韩国伦理在线| 自拍偷拍亚洲综合| 91精品在线视频观看| 免费不卡的av| 国产激情小视频在线| 久久精品美女视频| 伊人色综合影院| 毛片av中文字幕一区二区| 免费看欧美美女黄的网站| 久久九九全国免费| 97精品中文字幕| 精品国产成人亚洲午夜福利| 国产乱码精品一区二区三区中文| 嫩草黄色影院| 免费a级黄色片| 少妇被躁爽到高潮无码文| 亚洲天堂视频在线观看| 日韩精品专区在线影院观看| 性欧美办公室18xxxxhd| 91精品二区| 欧美亚洲另类在线观看| 91精品国产综合久| 在线观看h网址| 国产精品一线二线三线| jizz在线播放| 国产尤物视频在线观看| 狠狠色狠狠色综合婷婷tag| 欧美在线观看黄| 国产精品果冻传媒潘| 日本熟女一区二区| 一区二区三区国产好的精华液| 免费三级网站| 色呦哟—国产精品| 美女被内谢流白浆高视频| 1024在线看片你懂得| 欧美日韩国产综合久久| 亚洲高清国产拍精品26u| 黄a免费视频| 日本成人在线不卡| 日本不卡视频一二三区| 国产亚洲精品一区二区在线观看| av在线日韩| 青青青在线视频播放| 非洲黑人最猛性xxxx交| 成 人片 黄 色 大 片| 国产一区高清在线| 国产三级短视频| 青青久在线视频免费观看| gay欧美网站| 精品美女一区二区三区| 日本中文字幕网| 日本欧美精品久久久| 欧美一级免费在线观看| 蜜乳av一区| 在线观看免费版| 欧美激情影音先锋| 97在线看福利| 国产视频xxx| 97精品久久人人爽人人爽| 久热免费在线观看| 中国字幕a在线看韩国电影| 韩国日本在线视频| 日韩av电影一区| 久久久久久麻豆| 精品日本高清在线播放| 91精品国产91久久久久久三级| 超碰97久久国产精品牛牛| 一区二区久久久| 97久久综合精品久久久综合| 中文字幕日韩久久| 精品视频在线一区二区在线| 黄a在线观看| 少妇淫片在线影院| 四虎在线免费看| 韩国18福利视频免费观看| 免费久久久久久久久| 欧美成人精品激情在线观看| 欧美精品一区二区三区久久| 国产色无码精品视频国产| 欧美体内she精视频在线观看| 亚洲国产欧美日韩在线| 91麻豆成人久久精品二区三区| 日本少妇一级片| 午夜免费高清视频| 成年人视频网站在线| 国产精品最新在线观看| 国产精品色在线| 免费在线观看h|