要弄懂這個問題,首先你得知道靜態和動態指的是什麼。個人覺得卡耐基上的解釋很經典:
“The word static refers to things that happen at compile time and link time when the program is constructed—as opposed to load time or run time when the program is actually started.”
“The term dynamic refers to things that take place when a program is loaded and executed. ”
說白了,記憶體的靜態分配和動態分配的區別主要是兩個:
一是時間不同。靜態分配發生在程式編譯和串連的時候。動態分配則發生在程式調入和執行的時候。
二是空間不同。堆都是動態分配的,沒有靜態分配的堆。棧有2種分配方式:靜態分配和動態分配。靜態分配是編譯器完成的,比如局部變數的分配。動態分配由函數malloc進行分配。不過棧的動態分配和堆不同,他的動態分配是由編譯器進行釋放,無需我們手工實現。
對於一個進程的記憶體空間而言,可以在邏輯上分成3個部份:代碼區,待用資料區和動態資料區。動態資料區一般就是“堆棧”。“棧(stack)”和“堆(heap)”是兩種不同的動態資料區,棧是一種線性結構,堆是一種鏈式結構。進程的每個線程都有私人的“棧”,所以每個線程雖然代碼一樣,但本地變數的資料都是互不干擾。一個堆棧可以通過“基地址”和“棧頂”地址來描述。全域變數和靜態變數分配在待用資料區,本地變數分配在動態資料區,即堆棧中。程式通過堆棧的基地址和位移量來訪問本地變數。
一般,用static修飾的變數,全域變數位於待用資料區。函數調用過程中的參數,返回地址,EBP和局部變數都採用棧的方式存放。
其它:
所謂動態記憶體分配就是指在程式執行的過程中動態地分配或者回收儲存空間的分配記憶體的方法。動態記憶體分配不象數組等靜態記憶體配置方法那樣需要預先分配儲存空間,而是由系統根據程式的需要即時分配,且分配的大小就是程式要求的大小。
例如我們定義一個float型數組:float score[100];
但是,在使用數組的時候,總有一個問題困擾著我們:數組應該有多大?在很多的情況下,你並不能確定要使用多大的數組,比如上例,你可能並不知道我們要定義的這個數組到底有多大,那麼你就要把數組定義得足夠大。這樣,你的程式在運行時就申請了固定大小的你認為足夠大的記憶體空間。即使你知道你想利用的空間大小,但是如果因為某種特殊原因空間利用的大小有增加或者減少,你又必須重新去修改程式,擴大數組的儲存範圍。這種分配固定大小的記憶體配置方法稱之為靜態記憶體配置。但是這種記憶體配置的方法存在比較嚴重的缺陷,特別是處理某些問題時:在大多數情況下會浪費大量的記憶體空間,在少數情況下,當你定義的數組不夠大時,可能引起下標越界錯誤,甚至導致嚴重後果。
我們用動態記憶體分配就可以解決上面的問題. 所謂動態記憶體分配就是指在程式執行的過程中動態地分配或者回收儲存空間的分配記憶體的方法。動態記憶體分配不象數組等靜態記憶體配置方法那樣需要預先分配儲存空間,而是由系統根據程式的需要即時分配,且分配的大小就是程式要求的大小。從以上動、靜態記憶體配置比較可以知道動態記憶體分配相對於景泰記憶體配置的特點:
1、不需要預先分配儲存空間;
2、分配的空間可以根據程式的需要擴大或縮小。
要實現根據程式的需要動態分配儲存空間,就必須用到malloc函數.
malloc函數的原型為:void *malloc (unsigned int size) 其作用是在記憶體的動態儲存裝置區中分配一個長度為size的連續空間。其參數是一個無符號整形數,傳回值是一個指向所分配的連續儲存域的起始地址的指標。還有一點必須注意的是,當函數未能成功分配儲存空間(如記憶體不足)就會返回一個NULL指標。所以在調用該函數時應該檢測傳回值是否為NULL並執行相應的操作。
原文地址:http://hi.baidu.com/wu_yuzhi/blog/item/8bafc18a4922c2759f2fb4cb.html