malloc實現原理簡介

2021-06-21 09:34:06 字數 2439 閱讀 4560

malloc()是c語言中動態儲存管理 的一組標準庫函式之一。其作用是在記憶體的動態儲存區中分配乙個長度為size的連續空間。其引數是乙個無符號整形數,返回值 是乙個指向所分配的連續儲存域的起始位址的指標。 

動態記憶體分配 就 是指在程式執行的過程中動態地分配或者**儲存空間的分配記憶體的方法。動態記憶體分配不像陣列等靜態記憶體分配方法那樣需要預先分配儲存空間,而是由系統根據 程式的需要即時分配,且分配的大小就是程式要求的大小。本文簡單介紹動態記憶體分配函式malloc()及幾種實現方法。 

1. 簡介 

malloc()是c語言中動態儲存管理的一組標準庫函式之一。其作用是在記憶體的動態儲存區中分配乙個長度為size的連續空間。其引數是乙個無符號整形數,返回值是乙個指向所分配的連續儲存域的起始位址的指標。還有一點必須注意的是,當函式未能成功分配儲存空間(如記憶體不足 )就會返回乙個null指標。所以在呼叫該函式時應該檢測返回值是否為null並執行相應的操作。 

2. 函式說明 

c語言的動態儲存管理由一組標準庫函式實現,其原型在標準檔案裡描述,需要用這些功能時應包含這個檔案。與動態儲存分 配有關的函式共有四個,其中就包括儲存分配函式malloc()。函式原型是:void *malloc (size_t n);這裡的size_t是標準庫里定義的乙個型別,它是乙個無符號整型。這個整型能夠滿足所有對儲存塊大小描述的需要,具體相當於哪個整型由具體的c系 統確定。malloc的返回值為(void *)型別(這是通用指標的乙個重要用途),它分配一片能存放大小為n的資料的儲存塊,返回對應的指標值;如果不能滿足申請(找不到能滿足要求的儲存塊)就 返回null。在使用時,應該把malloc的返回值轉換到特定指標型別,賦給乙個指標。 

注意,雖然這裡的儲存塊是通過動態分配得到的,但 是它的大小也是確定的,同樣不允許越界使用。例如上面程式段分配的塊裡能存n個雙精度資料,隨後的使用就必須在這個範圍內進行。越界使用動態分配的儲存 塊,尤其是越界賦值,可能引起非常嚴重的後果,通常會破壞程式的執行系統,可能造成本程式或者整個計算機系統 垮台。 

下例是乙個動態分配的例子: 

#include

main() 

for (count=0;count〈10;count++) /*給陣列賦值*/ 

array[count]=count; 

for(count=0;count〈10;count++) /*列印陣列元素*/ 

printf("%2d",array[count]); 

} 上例中動態分配了10個整型儲存區域,然後進行賦值並列印。例中if((array(int *) malloc (10*sizeof(int)))==null)語句可以分為以下幾步: 

1)分配10個整型的連續儲存空間,並返回乙個指向其起始位址的整型指標 

2)把此整型指標位址賦給array 

3)檢測返回值是否為null 

3. malloc()工作機制 

malloc函式的實質體現在,它有乙個將可用的記憶體塊連線為乙個長長的列表的所謂空閒鍊錶。呼叫malloc函式時,它沿連線表尋找乙個大到足以滿足 使用者請求所需要的記憶體塊。然後,將該記憶體塊一分為二(一塊的大小與使用者請求的大小相等,另一塊的大小就是剩下的位元組)。接下來,將分配給使用者的那塊記憶體傳 給使用者,並將剩下的那塊(如果有的話)返回到連線表上。呼叫free函式時,它將使用者釋放的記憶體塊連線到空閒鏈上。到最後,空閒鏈會被切成很多的小記憶體片 段,如果這時使用者申請乙個大的記憶體片段,那麼空閒鏈上可能沒有可以滿足使用者要求的片段了。於是,malloc函式請求延時,並開始在空閒鏈上翻箱倒櫃地檢 查各記憶體片段,對它們進行整理,將相鄰的小空閒塊合併成較大的記憶體塊。 

附::c++中記憶體的動態分配與管理永遠是乙個讓c++開發者頭痛的問題,本文通過對c++中記憶體的動態分配釋放的基本原理的介紹,讓讀者朋友能對c++中的記憶體的動態分配與釋放有較為深入的理解,從而更好駕馭c++程式。

空閒鍊錶如何從中選擇分配記憶體塊?這是對問題(2)的解答。有下面四種選擇方法。

(1)首次適應法(first fit):鍊錶按塊位址排序。選擇第乙個滿足要求的空閒塊。特點:低位址碎片多,高位址碎片少。

(2)最佳適應法(best fit):鍊錶按空閒塊大小排序。選擇滿足要求的,且大小最小的空閒塊。特點:費時間,並且會出現很小的碎片。

(3)最壞適應法(worst fit):鍊錶按空閒塊大小排序。選擇最大的空閒塊。特點:碎片少,容易缺乏大塊。

(4)迴圈首次適應法(next fit):鍊錶按塊位址排序。從上次分配位置開始找到第乙個滿足要求的空閒塊。特點:碎片分布的又多又均勻。

如何處理被選空閒塊中的剩餘部分?這是對問題(3)的解答。一般來講,是要把剩餘的部分再插入回到空閒鍊錶中去的。要注意乙個空閒塊分割成兩個塊時,需要騰出若干位元組作為塊的頭部尾部等部分。

如何合併被釋放的塊?這是對問題(4)的解答。有兩種方法:立即合併、推遲合併。對於隱式空閒鍊錶,合併的具體過程是,

(1)前後塊都已分配:直接釋放當前塊即可;

(2)前塊分配、後塊空閒:和後塊合併;

(3)前塊空閒、後塊分配:和前塊合併;

(4)前後塊都已空閒:和前後塊合併;

malloc實現原理

malloc 是c語言中動態儲存管理 的一組標準庫函式之一。其作用是在記憶體的動態儲存區中分配乙個長度為size的連續空間。其引數是乙個無符號整形數,返回值 是乙個指向所分配的連續儲存域的起始位址的指標。動態記憶體分配 就 是指在程式執行的過程中動態地分配或者 儲存空間的分配記憶體的方法。動態記憶體...

malloc的實現原理

malloc 是 c語言中動態 儲存管理 的一組標準庫函式之一。其作用是在記憶體的動態儲存區中分配乙個長度為size的連續空間。其引數是乙個無符號整形數,返回值是乙個指向所分配的連續儲存域的起始位址的指標。動態記憶體分配 就 是指在程式執行的過程中動態地分配或者 儲存空間的分配記憶體的方法。動態記憶...

malloc的實現原理

malloc是c語言最常用的標準庫函式之一,用於在程式執行中動態地申請記憶體空間。我們都會使用它,其函式原型為 extern void malloc unsigned int num bytes 那麼它是怎麼實現的呢?不同的編譯環境中對它的實現可能不同。比如glibc the gnu c libra...