new malloc
https://blog.csdn.net/happyxieqiang/article/details/50775847
?
0.?????? 屬性
new/delete是C++關鍵字,需要編譯器支持。malloc/free是庫函數,需要頭文件支持。
1.?????? 參數
使用new操作符申請內存分配時無須指定內存塊的大小,編譯器會根據類型信息自行計算。而malloc則需要顯式地指出所需內存的尺寸。
2.?????? 返回類型
new操作符內存分配成功時,返回的是對象類型的指針,類型嚴格與對象匹配,無須進行類型轉換,故new是符合類型安全性的操作符。而malloc內存分配成功則是返回void * ,需要通過強制類型轉換將void*指針轉換成我們需要的類型。
3.?????? 分配失敗
new內存分配失敗時,會拋出bac_alloc異常。malloc分配內存失敗時返回NULL。
4.??????自定義類型
???????? new會先調用operator new函數,申請足夠的內存(通常底層使用malloc實現)。然后調用類型的構造函數,初始化成員變量,最后返回自定義類型指針。delete先調用析構函數,然后調用operator delete函數釋放內存(通常底層使用free實現)。
???????? malloc/free是庫函數,只能動態的申請和釋放內存,無法強制要求其做自定義類型對象構造和析構工作。
5.??????重載
C++允許重載new/delete操作符,特別的,布局new的就不需要為對象分配內存,而是指定了一個地址作為內存起始區域,new在這段內存上為對象調用構造函數完成初始化工作,并返回此地址。而malloc不允許重載。
6.?????? 內存區域
new操作符從自由存儲區(free store)上為對象動態分配內存空間,而malloc函數從堆上動態分配內存。自由存儲區是C++基于new操作符的一個抽象概念,凡是通過new操作符進行內存申請,該內存即為自由存儲區。而堆是操作系統中的術語,是操作系統所維護的一塊特殊內存,用于程序的內存動態分配,C語言使用malloc從堆上分配內存,使用free釋放已分配的對應內存。自由存儲區不等于堆,如上所述,布局new就可以不位于堆中。
?
?
今天偶然看到一個面試經驗中提到malloc和new的區別,突然發現自己雖然兩個都用過,但是至于區別,真的不是很明白 ,所以就仔細查了一些資料,算是對這個點徹底地了解一下,現在把我所學到的記錄下來。
malloc與free是C++/C語言的標準庫函數,new/delete是C++的運算符。它們都可用于申請動態內存和釋放內存。
1.malloc函數初探
首先我們要知道malloc是一個函數,malloc的全稱是memory allocation,中文叫動態內存分配。它的原型是:
void *malloc(int size);- 1
說明:malloc 向系統申請分配指定size個字節的內存空間,返回類型是 void* 類型。void* 表示未確定類型的指針。C,C++規定,void* 類型可以強制轉換為任何其它類型的指針。 ?
在這里注意:?
(1) void* 表示未確定類型的指針,更明確的說是指申請內存空間時還不知道用戶是用這段空間來存儲什么類型的數據(比如是char還是int或者…)?
(2) 使用malloc向系統申請內存時可能分配失敗。如果分配失敗,則返回一個空指針(NULL)。關于分配失敗的原因,有很多種,比如說空間不足就是一種。?
一個對應的釋放內存的函數:
- 1
該函數是將之前用malloc分配的空間還給程序或者是操作系統,也就是釋放了這塊內存,讓它重新得到自由。?
至于用法,其實這兩個函數用起來倒不是很難,也就是malloc()之后覺得不用了需要釋放把它給free()了,舉個簡單例子:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
當然,具體情況要具體分析以及具體解決。比如說,你定義了一個指針,在一個函數里申請了一塊內存然后通過函數返回傳遞給這個指針,那么也許釋放這塊內存這項工作就應該留給其他函數了。只要保證每個malloc()之后必須有一個free()與之對應。
關于這個函數的用法需要注意的一些地方:
1.申請了內存空間后,必須檢查是否分配成功。
2.當不需要再使用申請的內存時,記得釋放;釋放后應該把指向這塊內存的指針指向NULL,防止程序后面不小心使用了它。
3.這兩個函數應該是配對。如果申請后不釋放就是內存泄露;如果無故釋放那就是什么也沒有做。釋放只能一次,如果釋放兩次及兩次以上會出現錯誤(釋放空指針例外,釋放空指針其實也等于啥也沒做,所以釋放空指針釋放多少次都沒有問題)。
4.雖然malloc()函數的類型是void*,任何類型的指針都可以轉換成void*,但是最好還是在前面進行強制類型轉換,因為這樣可以躲過一些編譯器的檢查。
2.malloc函數深入
看了以上的內容我們大致知道malloc函數的初步內容以及它的用法,但是我們不知道malloc函數是怎么實現動態分配內存的。那它是怎么動態分配內存的呢?
答案是從堆里面獲得空間。也就是說函數返回的指針是指向堆里面的一塊內存。操作系統中有一個記錄空閑內存地址的鏈表。當操作系統收到程序的申請時,就會遍歷該鏈表,然后就尋找第一個空間大于所申請空間的堆結點,然后就將該結點從空閑結點鏈表中刪除,并將該結點的空間分配給程序。
說到這里就不得不提堆,什么是堆呢?堆是大家共有的空間,分全局堆和局部堆。全局堆就是所有沒有分配的空間,局部堆就是用戶分配的空間。堆在操作系統對進程 初始化的時候分配,運行過程中也可以向系統要額外的堆,記住一點:從堆申請的內存用完了要還給操作系統,也就是釋放,如果不還的話會發生內存泄露。
而所謂內存泄露就好比你去食堂吃飯,你吃完了之后沒把盤子拿走,這在別人看來是這個座有人占了,可怕的是你回頭吃飯又占了一個新座,你吃完之后還是沒把盤子拿走……終于,整個食堂的座位都被占滿了,食堂也亂套了。(比喻不太恰當,但大致是這個意思)
平常我們老說堆棧、堆棧,那棧又是什么呢?棧是線程獨有的,保存其運行狀態和局部自動變量的。棧在線程開始的時候初始化,每個線程的棧互相獨立。每個函數都有自己的棧,棧被用來在函數之間傳遞參數。操作系統在切換線程的時候會自動的切換棧,就是切換SS/ESP寄存器。棧空間不需要在高級語言里面顯式的分配和釋放。
通過上面對概念的描述,可以知道:
棧是由編譯器自動分配釋放,存放函數的參數值、局部變量的值等。操作方式類似于數據結構中的棧。
堆一般由程序員分配釋放,若不釋放,程序結束時可能由操作系統回收。注意這里說是可能,并非一定。所以堆一定要釋放!
3.new運算符
3.1 C++中,用new和delete動態創建和釋放數組或單個對象。?
動態創建對象時,只需指定其數據類型,而不必為該對象命名,new表達式返回指向該新創建對象的指針,我們可以通過指針來訪問此對象。
- 1
這個new表達式在堆區中分配創建了一個整型對象,并返回此對象的地址,并用該地址初始化指針pi 。
3.2 動態創建對象的初始化
動態創建的對象可以用初始化變量的方式初始化。
int *pi=new int(100); //指針pi所指向的對象初始化為100 string *ps=new string(10,'9');//*ps 為“9999999999”- 1
- 2
如果不提供顯示初始化,對于類類型,用該類的默認構造函數初始化;而內置類型的對象則無初始化。?
也可以對動態創建的對象做值初始化:
- 1
- 2
- 3
3.3 撤銷動態創建的對象?
delete表達式釋放指針指向的地址空間。
- 1
- 2
如果指針指向的不是new分配的內存地址,則使用delete是不合法的。
3.4 在delete之后,重設指針的值
delete p;- 1
執行完該語句后,p變成了不確定的指針,在很多機器上,盡管p值沒有明確定義,但仍然存放了它之前所指對象的地址,然后p所指向的內存已經被釋放了,所以p不再有效。此時,該指針變成了懸垂指針(懸垂指針指向曾經存放對象的內存,但該對象已經不存在了)。懸垂指針往往導致程序錯誤,而且很難檢測出來。?
一旦刪除了指針所指的對象,立即將指針置為0,這樣就非常清楚的指明指針不再指向任何對象。(零值指針:int *ip=0;)
3.5 區分零值指針和NULL指針
零值指針,是值是0的指針,可以是任何一種指針類型,可以是通用變體類型void*也可以是char*,int*等等。?
空指針,其實空指針只是一種編程概念,就如一個容器可能有空和非空兩種基本狀態,而在非空時可能里面存儲了一個數值是0,因此空指針是人為認為的指針不提供任何地址訊息。
4.malloc和new的區別
(1)?new 返回指定類型的指針,并且可以自動計算所需要大小。而 malloc 則必須要由我們計算字節數,并且在返回后強行轉換為實際類型的指針。?
例:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
(2)?malloc 只管分配內存,并不能對所得的內存進行初始化,所以得到的一片新內存中,其值將是隨機的。new創建的對象可以用初始化變量的方式初始化。
除了分配及最后釋放的方法不一樣以外,通過malloc或new得到指針,在其它操作上保持一致。
轉載于:https://www.cnblogs.com/diegodu/p/9190717.html
總結
以上是生活随笔為你收集整理的new malloc的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 期货大赛项目|九,fileinput插件
- 下一篇: plsqldevelop安装教程