1. 程式人生 > >靜態記憶體,棧記憶體和動態分配的記憶體(堆記憶體)的區別

靜態記憶體,棧記憶體和動態分配的記憶體(堆記憶體)的區別

(1) 從靜態儲存區域分配。記憶體在程式編譯的時候就已經分配好,這塊記憶體在程式的整個執行期間都存在。例如全域性變數,static變數。
(2) 在棧上建立。在執行函式時,函式內區域性變數的儲存單元都可以在棧上建立,函式執行結束時這些儲存單元自動被釋放。棧記憶體分配運算內置於處理器的指令集中,效率很高,但是分配的記憶體容量有限。
(3) 從堆上分配,亦稱動態記憶體分配。程式在執行的時候用malloc或new申請任意多少的記憶體,程式設計師自己負責在何時用free或delete釋放記憶體。動態記憶體的生存期由我們決定,使用非常靈活,但問題也最多。因此,試圖返回一個棧上分配的記憶體將會引發未知錯誤。

char *GetString(void)
{
char p[] = "hello world";
return p; // 編譯器將提出警告
}
p是在棧上分配的記憶體,函式結束後將會自動釋放,p指向的記憶體區域內容不是"hello world",而是未知的內容。

如果是返回靜態儲存的記憶體呢:
char *GetString(void)
{
char *p = "hello world";
return p;
}
這裡“hello world”是常量字串,位於靜態儲存區,它在程式生命期內恆定不變。無論什麼時候呼叫GetString,它返回的始終是同一個“只讀”的記憶體塊。


--------------------------------
在標準C語言上,使用malloc等記憶體分配函式獲取記憶體既是從堆中分配記憶體,而在一個函式體中例如定義一個數組之類的操作是從棧中分配記憶體。
char * p這個p指標是儲存在棧中,但它的內容是你malloc的堆記憶體的地址

,return 
p時,不是返回p的地址,而是p指向的地址內容.這個時候,由於p指向的地址內容是用malloc在堆上分配的,所以是有效的.
動態記憶體堆,C++中由new和delete來分配和釋放,C中由malloc和free來分配和釋放,它的生命週期是動態的,可以由程式設計師來建立和銷燬。當然程式結束自動釋放。
return p;的時候會在記憶體中產生一個匿名的指標,子函式執行結束p變數消亡,執行語句str = GetMemory(100); 
此時匿名指標變數賦值給str指標。
至於記憶體空間,由於是在堆中申請所以沒有顯示的釋放,則會在程式結束才被釋放,也就是在free之前,該空間一直存在。