在C++中,內存分紅5個區,他們分別是堆、棧、自由存儲區、全局/靜態存儲區和常量存儲區。程序員
在執行函數時,函數內局部變量的存儲單元均可以在棧上建立,函數執行結束時這些存儲單元自動被釋放。棧內存分配運算內置於處理器的指令集中,效率很高,可是分配的內存容量有限。
是由編譯器在須要時自動分配,不須要時自動清除的變量存儲區。一般存放局部變量、函數參數等。windows
就是那些由new分配的內存塊,他們的釋放編譯器不去管,由咱們的應用程序(程序員)去控制,通常一個new就要對應一個delete,一個new[]與一個delete[]對應。若是程序員沒有釋放掉,那麼在程序結束後,操做系統會自動回收。數組
就是那些由malloc等分配的內存塊,他和堆是十分類似的,不過它是用free來結束本身的生命的。數據結構
全局變量和靜態變量被分配到同一塊內存中(在之前的C語言中,全局變量又分爲初始化的和未初始化的,在C++裏面沒有這個區分了,他們共同佔用同一塊內存區。)函數
這是一塊比較特殊的存儲區,他們裏面存放的是常量,不容許修改。操作系統
(注意:堆和自由存儲區其實不過是同一塊區域,new底層實現代碼中調用了malloc,new能夠當作是malloc智能化的高級版本)指針
堆: 操做系統有一個記錄空閒內存地址的鏈表,當系統收到程序的申請時,會遍歷該鏈表,尋找第一個空間大於所申請空間的堆結點,而後將該結點從空閒結點鏈表中刪 除,並將該結點的空間分配給程序,另外,對於大多數系統,會在這塊內存空間中的首地址處記錄本次分配的大小,這樣代碼 中的delete語句才能正確的釋放本內存空間。咱們常說的內存泄露,最多見的就是堆泄露(還有資源泄露),它是指程序在運行中出現泄露,若是程序被關閉掉的話,操做系統會幫助釋放泄露的內存。code
棧: 在函數調用時第一個進棧的主函數中的下一條指令(函數調用語句的下一條可執行語句)的地址而後是函數 的各個參數,在大多數的C編譯器中,參數是由右往左入棧,而後是函數中的局部變量。對象
管理方式:隊列
系統響應:
空間大小:
碎片問題:
生長方向:
分配方式:
分配效率:
(1)指針變量沒有被初始化。任何指針變量剛被建立時不會自動成爲NULL指針,它的缺省值是隨機的,它會亂指一氣。因此,指針變量在建立的同時應當被初始化,要麼將指針設置爲NULL,要麼讓它指向合法的內存。
(2)指針p被free或者delete以後,沒有置爲NULL,讓人誤覺得p是個合法的指針。
malloc與free是C++/C語言的標準庫函數,new/delete是C++的運算符。 它們均可用於申請動態內存和釋放內存。
對於非內部數據類型的對象而言,光用maloc/free沒法知足動態對象的要求。對象在建立的同時要自動執行構造函數,對象在消亡以前要自動執行析構函數。因爲malloc/free是庫函數而不是運算符,不在編譯器控制權限以內,不可以把執行構造函數和析構函數的任務強加於malloc/free。
所以C++語言須要一個能完成動態內存分配和初始化工做的運算符new,以及一個能完成清理與釋放內存工做的運算符delete。注意new/delete不是庫函數。
既然new/delete的功能徹底覆蓋了malloc/free,爲何C++不把malloc/free淘汰出局呢?這是由於C++程序常常要調用C函數,而C程序只能用malloc/free管理動態內存。
若是用free釋放「new建立的動態對象」,那麼該對象因沒法執行析構函數而可能致使程序出錯。若是用delete釋放「malloc申請的動態內存」,結果也會致使程序出錯,可是該程序的可讀性不好。因此new/delete必須配對使用,malloc/free也同樣。
C++ 提供了一種「動態內存分配」機制,使得程序能夠在運行期間,根據實際須要,要求操做系統臨時分配一片內存空間用於存放數據。此種內存分配是在程序運行中進行的,而不是在編譯時就肯定的,所以稱爲「動態內存分配」。
在 C++ 中,經過 new 運算符來實現動態內存分配。
new 運算符的第一種用法:
T \*p = new T; 其中,T 是任意類型名,p 是類型爲 T\* 的[指針] **new 運算符還有第二種用法,用來動態分配一個任意大小的數組:**
T *p =new T[N];
//其中,T 是任意類型名,p 是類型爲 T* 的指針,N 表明「元素個數」,能夠是任何值爲正整數的表達式,表達式中能夠包含變量、函數調用等。這樣的語句動態分配出 N × sizeof(T) 個字節的內存空間,這片空間的起始地址被賦值給 p。
程序從操做系統動態分配所得的內存空間在使用完後應該釋放,交還操做系統,以便操做系統將這片內存空間分配給其餘程序使用。C++ 提供 delete 運算符,用以釋放動態分配的內存空間。delete 運算符的基本用法以下:
delete p;
若是是用 new 的第二種用法分配的內存空間,即動態分配了一個數組,那麼釋放該數組時,應以以下形式使用 delete 運算符:
delete\[\] p;
牢記,用 new 運算符動態分配的內存空間,必定要用 delete 運算符釋放。不然,即使程序運行結束,這部份內存空間仍然不會被操做系統收回,從而成爲被白白浪費掉的內存垃圾。這種現象也稱爲「內存泄露」。