new和malloc的區(qū)別與聯(lián)系


我們都知道new和malloc都可以用來申請(qǐng)空間,但為什么有了malloc/free為什么還要new/delete?如果new/delete的功能完全覆蓋了malloc/free,為什么C++不把malloc/free淘汰出局呢?這些將是我接下來要討論的問題。。。

首先,我們先來了解一下new和malloc之間的區(qū)別:
屬性方面
new/delete作為C++關(guān)鍵字,需要編譯器支持。malloc/free屬于庫(kù)函數(shù),需要頭文件(stdlib.h)支持。
參數(shù)方面
new申請(qǐng)內(nèi)存無需指定內(nèi)存大小,編譯器會(huì)根據(jù)類型信息自行計(jì)算。除此之外,new會(huì)調(diào)用構(gòu)造函數(shù)。
malloc必須由我們計(jì)算需要申請(qǐng)的字節(jié)數(shù),需要指出所需內(nèi)存的尺寸,并且返回后強(qiáng)行轉(zhuǎn)換為實(shí)際類型的指針。而且malloc只管分配內(nèi)存,并不能對(duì)所得的內(nèi)存進(jìn)行初始化,所以得到的一片新內(nèi)存中,其值是隨機(jī)的。


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


分配失敗方面
new內(nèi)存分配失敗的時(shí)候,拋出bad_ alloc異常 ;malloc分配內(nèi)存失敗時(shí)返回NULL。
自定義類型
new會(huì)先調(diào)用operator new函數(shù),申請(qǐng)足夠的內(nèi)存(通常底層使用malloc實(shí)現(xiàn)).然后調(diào)用類型的構(gòu)造函數(shù),初始化成員變量,最后返回自定義類型指針。delete先調(diào)用析構(gòu)函數(shù),然后調(diào)用operator delete函數(shù)釋放內(nèi)存(通常底層使用free實(shí)現(xiàn))。
malloc/free是庫(kù)函數(shù),只能動(dòng)態(tài)的申請(qǐng)和釋放內(nèi)存,無法強(qiáng)制要求其做自定義類型對(duì)象構(gòu)造和析構(gòu)工作。
重載
C++允許重載new/delete操作符,而malloc是庫(kù)函數(shù)不允許重載。
內(nèi)存區(qū)域方面
new在自由儲(chǔ)存區(qū)分配內(nèi)存,malloc在堆上分配內(nèi)存。
自由存儲(chǔ)區(qū)(free store)是C++中通過new和delete動(dòng)態(tài)分配和釋放對(duì)象的抽象概念(邏輯概念),通過new來申請(qǐng)的內(nèi)存區(qū)域可稱為自由存儲(chǔ)區(qū),通過delete歸還內(nèi)存。
堆是操作系統(tǒng)所維護(hù)的一塊特殊內(nèi)存,是一個(gè)物理概念,它提供了動(dòng)態(tài)分配的功能,當(dāng)運(yùn)行程序調(diào)用malloc()時(shí)就會(huì)從中分配,調(diào)用free()歸還內(nèi)存。
效率方面
對(duì)于new和delete,對(duì)象在創(chuàng)建的同時(shí)要自動(dòng)執(zhí)行構(gòu)造函數(shù),對(duì)象在消亡之前要自動(dòng)執(zhí)行析構(gòu)函數(shù)。由于malloc/free是庫(kù)函數(shù)而不是運(yùn)算符,不在編譯器控制權(quán)限之內(nèi),不能夠把執(zhí)行構(gòu)造函數(shù)和析構(gòu)函數(shù)的任務(wù)強(qiáng)加于malloc/free。所以說new的效率高于malloc。

最后我們?cè)賮斫鉀Q一下開頭提到的問題:
有了malloc/free為什么還要new/delete?
因?yàn)镃++語(yǔ)言需要一個(gè)能完成動(dòng)態(tài)內(nèi)存分配和初始化工作的運(yùn)算符new,以及一個(gè)能完成清理與釋放內(nèi)存工作的運(yùn)算符delete,講究一個(gè)效率。對(duì)于內(nèi)部數(shù)據(jù)類型的“對(duì)象”沒有構(gòu)造與析構(gòu)的過程,對(duì)它們而言malloc/free和new/delete是等價(jià)的。但對(duì)于非內(nèi)部數(shù)據(jù)類型(需要用戶自己定義),new和malloc的區(qū)別就顯而易見。
既然new/delete的功能完全覆蓋了malloc/free,為什么C++不把malloc/free淘汰出局呢?
C++程序經(jīng)常要調(diào)用C函數(shù),而C程序只能用malloc/free管理動(dòng)態(tài)內(nèi)存。
如果用free釋放“new創(chuàng)建的動(dòng)態(tài)對(duì)象”,那么該對(duì)象因無法執(zhí)行析構(gòu)函數(shù)而可能導(dǎo)致程序出錯(cuò)。如果用delete釋放“malloc申請(qǐng)的動(dòng)態(tài)內(nèi)存”,結(jié)果也會(huì)導(dǎo)致程序出錯(cuò)。所以new/delete必須配對(duì)使用,malloc/free也一樣。

