記憶體的靜態分配和動態分配的區別主要是兩個:
一是時間不同。靜態分配發生在程式編譯和連線的時候。動態分配則發生在程式調入和執行的時候。
二是空間不同。堆都是動態分配的,沒有靜態分配的堆。棧有2種分配方式:靜態分配和動態分配。靜態分配是編譯器完成的,比如區域性變數的分配。動態分配由函式malloc進行分配。不過棧的動態分配和堆不同,他的動態分配是由編譯器進行釋放,無需我們手工實現。
對於一個程序的記憶體空間而言,可以在邏輯上分成3個部份:程式碼區,靜態資料區和動態資料區。
動態資料區一般就是“堆疊”。“棧(stack)”和“堆(heap)”是兩種不同的動態資料區,棧是一種線性結構,堆是一種鏈式結構。程序的每個執行緒都有私有的“棧”,所以每個執行緒雖然程式碼一樣,但本地變數的資料都是互不干擾。一個堆疊可以透過“基地址”和“棧頂”地址來描述。全域性變數和靜態變數分配在靜態資料區,本地變數分配在動態資料區,即堆疊中。程式透過堆疊的基地址和偏移量來訪問本地變數。
一般,用static修飾的變數,全域性變數位於靜態資料區。函式呼叫過程中的引數,返回地址,EBP和區域性變數都採用棧的方式存放。
所謂動態記憶體分配就是指在程式執行的過程中動態地分配或者回收儲存空間的分配記憶體的方法。動態記憶體分配不象陣列等靜態記憶體分配方法那樣需要預先分配儲存空間,而是由系統根據程式的需要即時分配,且分配的大小就是程式要求的大小。
例如我們定義一個float型陣列:
float score[100];
但是,在使用陣列的時候,總有一個問題困擾著我們:陣列應該有多大?在很多的情況下,你並不能確定要使用多大的陣列,比如上例,你可能並不知道我們要定義的這個陣列到底有多大,那麼你就要把陣列定義得足夠大。這樣,你的程式在執行時就申請了固定大小的你認為足夠大的記憶體空間。即使你知道你想利用的空間大小,但是如果因為某種特殊原因空間利用的大小有增加或者減少,你又必須重新去修改程式,擴大陣列的儲存範圍。這種分配固定大小的記憶體分配方法稱之為靜態記憶體分配。但是這種記憶體分配的方法存在比較嚴重的缺陷,特別是處理某些問題時:在大多數情況下會浪費大量的記憶體空間,在少數情況下,當你定義的陣列不夠大時,可能引起下標越界錯誤,甚至導致嚴重後果。
我們用動態記憶體分配就可以解決上面的問題. 所謂動態記憶體分配就是指在程式執行的過程中動態地分配或者回收儲存空間的分配記憶體的方法。動態記憶體分配不象陣列等靜態記憶體分配方法那樣需要預先分配儲存空間,而是由系統根據程式的需要即時分配,且分配的大小就是程式要求的大小。從以上動、靜態記憶體分配比較可以知道動態記憶體分配相對於景泰記憶體分配的特點:
1、不需要預先分配儲存空間;
2、分配的空間可以根據程式的需要擴大或縮小。
要實現根據程式的需要動態分配儲存空間,就必須用到malloc函式.
malloc函式的原型為:void *malloc (unsigned int size) 其作用是在記憶體的動態儲存區中分配一個長度為size的連續空間。其引數是一個無符號整形數,返回值是一個指向所分配的連續儲存域的起始地址的指標。還有一點必須注意的是,當函式未能成功分配儲存空間(如記憶體不足)就會返回一個NULL指標。所以在呼叫該函式時應該檢測返回值是否為NULL並執行相應的操作。
靜態記憶體是在程式一開始執行就會分配記憶體,直到程式結束了,記憶體才被釋放。
動態記憶體是在程式呼叫在程式中定義的函式時才被分配,函式呼叫結束了,動態記憶體就釋放。
記憶體的靜態分配和動態分配的區別主要是兩個:
一是時間不同。靜態分配發生在程式編譯和連線的時候。動態分配則發生在程式調入和執行的時候。
二是空間不同。堆都是動態分配的,沒有靜態分配的堆。棧有2種分配方式:靜態分配和動態分配。靜態分配是編譯器完成的,比如區域性變數的分配。動態分配由函式malloc進行分配。不過棧的動態分配和堆不同,他的動態分配是由編譯器進行釋放,無需我們手工實現。
對於一個程序的記憶體空間而言,可以在邏輯上分成3個部份:程式碼區,靜態資料區和動態資料區。
動態資料區一般就是“堆疊”。“棧(stack)”和“堆(heap)”是兩種不同的動態資料區,棧是一種線性結構,堆是一種鏈式結構。程序的每個執行緒都有私有的“棧”,所以每個執行緒雖然程式碼一樣,但本地變數的資料都是互不干擾。一個堆疊可以透過“基地址”和“棧頂”地址來描述。全域性變數和靜態變數分配在靜態資料區,本地變數分配在動態資料區,即堆疊中。程式透過堆疊的基地址和偏移量來訪問本地變數。
一般,用static修飾的變數,全域性變數位於靜態資料區。函式呼叫過程中的引數,返回地址,EBP和區域性變數都採用棧的方式存放。
所謂動態記憶體分配就是指在程式執行的過程中動態地分配或者回收儲存空間的分配記憶體的方法。動態記憶體分配不象陣列等靜態記憶體分配方法那樣需要預先分配儲存空間,而是由系統根據程式的需要即時分配,且分配的大小就是程式要求的大小。
例如我們定義一個float型陣列:
float score[100];
但是,在使用陣列的時候,總有一個問題困擾著我們:陣列應該有多大?在很多的情況下,你並不能確定要使用多大的陣列,比如上例,你可能並不知道我們要定義的這個陣列到底有多大,那麼你就要把陣列定義得足夠大。這樣,你的程式在執行時就申請了固定大小的你認為足夠大的記憶體空間。即使你知道你想利用的空間大小,但是如果因為某種特殊原因空間利用的大小有增加或者減少,你又必須重新去修改程式,擴大陣列的儲存範圍。這種分配固定大小的記憶體分配方法稱之為靜態記憶體分配。但是這種記憶體分配的方法存在比較嚴重的缺陷,特別是處理某些問題時:在大多數情況下會浪費大量的記憶體空間,在少數情況下,當你定義的陣列不夠大時,可能引起下標越界錯誤,甚至導致嚴重後果。
我們用動態記憶體分配就可以解決上面的問題. 所謂動態記憶體分配就是指在程式執行的過程中動態地分配或者回收儲存空間的分配記憶體的方法。動態記憶體分配不象陣列等靜態記憶體分配方法那樣需要預先分配儲存空間,而是由系統根據程式的需要即時分配,且分配的大小就是程式要求的大小。從以上動、靜態記憶體分配比較可以知道動態記憶體分配相對於景泰記憶體分配的特點:
1、不需要預先分配儲存空間;
2、分配的空間可以根據程式的需要擴大或縮小。
要實現根據程式的需要動態分配儲存空間,就必須用到malloc函式.
malloc函式的原型為:void *malloc (unsigned int size) 其作用是在記憶體的動態儲存區中分配一個長度為size的連續空間。其引數是一個無符號整形數,返回值是一個指向所分配的連續儲存域的起始地址的指標。還有一點必須注意的是,當函式未能成功分配儲存空間(如記憶體不足)就會返回一個NULL指標。所以在呼叫該函式時應該檢測返回值是否為NULL並執行相應的操作。
靜態記憶體是在程式一開始執行就會分配記憶體,直到程式結束了,記憶體才被釋放。
動態記憶體是在程式呼叫在程式中定義的函式時才被分配,函式呼叫結束了,動態記憶體就釋放。