new與malloc的區(qū)別

1. 屬性

new/delete是C++關(guān)鍵字,需要編譯器支持惩琉。malloc/free是庫(kù)函數(shù)豆励,需要頭文件支持。

2. 參數(shù)

使用new操作符申請(qǐng)內(nèi)存分配時(shí)無(wú)須指定內(nèi)存塊的大小琳水,編譯器會(huì)根據(jù)類(lèi)型信息自行計(jì)算肆糕。而malloc則需要顯式地指出所需內(nèi)存的尺寸。

3. 返回類(lèi)型

new操作符內(nèi)存分配成功時(shí)在孝,返回的是對(duì)象類(lèi)型的指針诚啃,類(lèi)型嚴(yán)格與對(duì)象匹配,無(wú)須進(jìn)行類(lèi)型轉(zhuǎn)換私沮,故new是符合類(lèi)型安全性的操作符始赎。而malloc內(nèi)存分配成功則是返回void * ,需要通過(guò)強(qiáng)制類(lèi)型轉(zhuǎn)換將void*指針轉(zhuǎn)換成我們需要的類(lèi)型。

4. 調(diào)用構(gòu)造函數(shù)/析構(gòu)函數(shù)

使用new操作符來(lái)分配對(duì)象內(nèi)存時(shí)會(huì)經(jīng)歷三個(gè)步驟:

  1. 調(diào)用operator new 函數(shù)(對(duì)于數(shù)組是operator new[])分配一塊足夠大的造垛,原始的魔招,未命名的內(nèi)存空間以便存儲(chǔ)特定類(lèi)型的對(duì)象。
  2. 編譯器運(yùn)行相應(yīng)的構(gòu)造函數(shù)以構(gòu)造對(duì)象五辽,并為其傳入初值办斑。
  3. 對(duì)象構(gòu)造完成后,返回一個(gè)指向該對(duì)象的指針杆逗。

使用delete操作符來(lái)釋放對(duì)象內(nèi)存時(shí)會(huì)經(jīng)歷兩個(gè)步驟:

  1. 調(diào)用對(duì)象的析構(gòu)函數(shù)乡翅。
  2. 編譯器調(diào)用operator delete(或operator delete[])函數(shù)釋放內(nèi)存空間。

5. 對(duì)數(shù)組的處理

C++提供了new[]與delete[]來(lái)專(zhuān)門(mén)處理數(shù)組類(lèi)型:

A * ptr = new A[10]; //分配10個(gè)A對(duì)象

使用new[]分配的內(nèi)存必須使用delete[]進(jìn)行釋放:

delete [] ptr;

new對(duì)數(shù)組的支持體現(xiàn)在它會(huì)分別調(diào)用構(gòu)造函數(shù)函數(shù)初始化每一個(gè)數(shù)組元素罪郊,釋放對(duì)象時(shí)為每個(gè)對(duì)象調(diào)用析構(gòu)函數(shù)蠕蚜。注意delete[]要與new[]配套使用,不然會(huì)找出數(shù)組對(duì)象部分釋放的現(xiàn)象悔橄,造成內(nèi)存泄漏靶累。
使用malloc分配一個(gè)數(shù)組的內(nèi)存,需要指定數(shù)組的大醒⑴薄:

int * ptr = (int *) malloc( sizeof(int)* 10 ); //分配一個(gè)10個(gè)int元素的數(shù)組

6. 重載

C++允許重載new/delete操作符opeartor new /operator delete函數(shù)挣柬;malloc/free不允許重載。

7. 內(nèi)存區(qū)域

new操作符從自由存儲(chǔ)區(qū)(free store)上為對(duì)象動(dòng)態(tài)分配內(nèi)存空間争舞,而malloc函數(shù)從堆上動(dòng)態(tài)分配內(nèi)存凛忿。自由存儲(chǔ)區(qū)是C++基于new操作符的一個(gè)抽象概念澈灼,凡是通過(guò)new操作符進(jìn)行內(nèi)存申請(qǐng)竞川,該內(nèi)存即為自由存儲(chǔ)區(qū)。而堆是操作系統(tǒng)中的術(shù)語(yǔ)叁熔,是操作系統(tǒng)所維護(hù)的一塊特殊內(nèi)存委乌,用于程序的內(nèi)存動(dòng)態(tài)分配遭贸,C語(yǔ)言使用malloc從堆上分配內(nèi)存心软,使用free釋放已分配的對(duì)應(yīng)內(nèi)存删铃。自由存儲(chǔ)區(qū)不等于堆,如上所述咒劲,布局new就可以不位于堆中。(TODO:自由存儲(chǔ)區(qū)與堆的區(qū)別帐偎?

8. 內(nèi)存分配失敗

new內(nèi)存分配失敗時(shí)削樊,會(huì)拋出bac_alloc異常兔毒。malloc分配內(nèi)存失敗時(shí)返回NULL。
在operator new拋出異常以反映一個(gè)未獲得滿(mǎn)足的需求之前绕辖,它會(huì)先調(diào)用一個(gè)用戶(hù)指定的錯(cuò)誤處理函數(shù)仪际,這就是new_handler昵骤。new_handler是一個(gè)指針類(lèi)型:

namespace std
{
    typedef void (*new_handler)();
}

指向了一個(gè)沒(méi)有參數(shù)沒(méi)有返回值的函數(shù),即為錯(cuò)誤處理函數(shù)成榜。為了指定錯(cuò)誤處理函數(shù)赎婚,用戶(hù)需要調(diào)用set_new_handler樱溉,這是一個(gè)聲明于標(biāo)準(zhǔn)庫(kù)的函數(shù):

namespace std
{
    new_handler set_new_handler(new_handler p ) throw();
}

set_new_handler的參數(shù)為new_handler指針,指向了operator new 無(wú)法分配足夠內(nèi)存時(shí)該調(diào)用的函數(shù)撩嚼。其返回值也是個(gè)指針完丽,指向set_new_handler被調(diào)用前正在執(zhí)行(但馬上就要發(fā)生替換)的那個(gè)new_handler函數(shù)拇舀。
當(dāng)new_handler執(zhí)行并返回之后,之前失敗的內(nèi)存分配操作會(huì)重新進(jìn)行瓷耙,如果仍然分配失敗朱躺,分配函數(shù)(operator new, operator new[])會(huì)繼續(xù)調(diào)用new_handler长搀,周而復(fù)始源请,直到new_handler==nullptr彻况,分配函數(shù)會(huì)拋出std::bad_alloc異常。

9. 直觀(guān)地重新分配內(nèi)存

使用malloc分配的內(nèi)存后良蛮,如果在使用過(guò)程中發(fā)現(xiàn)內(nèi)存不足悍赢,可以使用realloc函數(shù)進(jìn)行內(nèi)存重新分配實(shí)現(xiàn)內(nèi)存的擴(kuò)充。realloc先判斷當(dāng)前的指針?biāo)竷?nèi)存是否有足夠的連續(xù)空間左权,如果有赏迟,原地?cái)U(kuò)大可分配的內(nèi)存地址,并且返回原來(lái)的地址指針甩栈;如果空間不夠谤职,先按照新指定的大小分配空間,將原有數(shù)據(jù)從頭到尾拷貝到新分配的內(nèi)存區(qū)域,而后釋放原來(lái)的內(nèi)存區(qū)域冤吨。
new沒(méi)有這樣直觀(guān)的配套設(shè)施來(lái)擴(kuò)充內(nèi)存漩蟆。(實(shí)際使用中,可能只有想對(duì)數(shù)組擴(kuò)容時(shí)圾叼,才會(huì)遇到這種情況)


參考資料:

[1] 經(jīng)典面試題之new和malloc的區(qū)別
[2] 細(xì)說(shuō)new與malloc的10點(diǎn)區(qū)別
[3] cppreference: set_new_handler

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市构挤,隨后出現(xiàn)的幾起案子筋现,更是在濱河造成了極大的恐慌箱歧,老刑警劉巖,帶你破解...
    沈念sama閱讀 212,383評(píng)論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件洒沦,死亡現(xiàn)場(chǎng)離奇詭異微谓,居然都是意外死亡输钩,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,522評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門(mén)姻氨,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)肴焊,“玉大人娶眷,你說(shuō)我怎么就攤上這事啸臀。” “怎么了乘粒?”我有些...
    開(kāi)封第一講書(shū)人閱讀 157,852評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵轧铁,是天一觀(guān)的道長(zhǎng)旦棉。 經(jīng)常有香客問(wèn)我药薯,道長(zhǎng)童本,這世上最難降的妖魔是什么系谐? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,621評(píng)論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮纪他,結(jié)果婚禮上茶袒,老公的妹妹穿的比我還像新娘。我一直安慰自己薪寓,他們只是感情好向叉,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,741評(píng)論 6 386
  • 文/花漫 我一把揭開(kāi)白布瘦黑。 她就那樣靜靜地躺著,像睡著了一般幸斥。 火紅的嫁衣襯著肌膚如雪甲葬。 梳的紋絲不亂的頭發(fā)上懈贺,一...
    開(kāi)封第一講書(shū)人閱讀 49,929評(píng)論 1 290
  • 那天,我揣著相機(jī)與錄音钠至,去河邊找鬼。 笑死屿脐,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的万栅。 我是一名探鬼主播,決...
    沈念sama閱讀 39,076評(píng)論 3 410
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼休溶,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼兽掰!你這毒婦竟也來(lái)了孽尽?” 一聲冷哼從身側(cè)響起忧勿,我...
    開(kāi)封第一講書(shū)人閱讀 37,803評(píng)論 0 268
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤鸳吸,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后坎拐,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體廉白,經(jīng)...
    沈念sama閱讀 44,265評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡乖寒,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,582評(píng)論 2 327
  • 正文 我和宋清朗相戀三年楣嘁,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了逐虚。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,716評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖买雾,靈堂內(nèi)的尸體忽然破棺而出杨帽,到底是詐尸還是另有隱情注盈,我是刑警寧澤叙赚,帶...
    沈念sama閱讀 34,395評(píng)論 4 333
  • 正文 年R本政府宣布震叮,位于F島的核電站,受9級(jí)特大地震影響朴则,放射性物質(zhì)發(fā)生泄漏乌妒。R本人自食惡果不足惜撤蚊,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,039評(píng)論 3 316
  • 文/蒙蒙 一侦啸、第九天 我趴在偏房一處隱蔽的房頂上張望丧枪。 院中可真熱鬧,春花似錦忘闻、人聲如沸齐佳。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,798評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至命爬,卻和暖如春辐脖,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背皆愉。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,027評(píng)論 1 266
  • 我被黑心中介騙來(lái)泰國(guó)打工嗜价, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人幕庐。 一個(gè)月前我還...
    沈念sama閱讀 46,488評(píng)論 2 361
  • 正文 我出身青樓久锥,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親异剥。 傳聞我的和親對(duì)象是個(gè)殘疾皇子瑟由,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,612評(píng)論 2 350

推薦閱讀更多精彩內(nèi)容