malloc()函式的工作機制

2021-05-22 00:31:45 字數 1966 閱讀 5132

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

malloc()在作業系統中的實現

在 c 程式中,多次使用malloc () 和 free()。不過,您可能沒有用一些時間去思考它們在您的作業系統中是如何實現的。本節將向您展示 malloc 和 free 的乙個最簡化實現的**來幫助說明管理記憶體時都涉及到了哪些事情。

在大部分作業系統中,記憶體分配由以下兩個簡單的函式來處理:

void *malloc (long numbytes):該函式負責分配 numbytes 大小的記憶體,並返回指向第乙個位元組的指標。

void free(void *firstbyte):如果給定乙個由先前的 malloc 返回的指標,那麼該函式會將分配的空間歸還給程序的「空閒空間」。

malloc_init 將是初始化記憶體分配程式的函式。它要完成以下三件事:將分配程式標識為已經初始化,找到系統中最後乙個有效記憶體位址,然後建立起指向我們管理的記憶體的指標。這三個變數都是全域性變數:

//清單 1. 我們的簡單分配程式的全域性變數

int has_initialized = 0;

void *managed_memory_start;

void *last_valid_address;

如前所述,被對映的記憶體的邊界(最後乙個有效位址)常被稱為系統中斷點或者 當前中斷點。在很多 unix? 系統中,為了指出當前系統中斷點,必須使用  sbrk(0) 函式。 sbrk 根據引數中給出的位元組數移動當前系統中斷點,然後返回新的系統中斷點。使用引數 0 只是返回當前中斷點。這裡是我們的 malloc 初始化**,它將找到當前中斷點並初始化我們的變數:

複製**

清單 2. 分配程式初始化函式

/* include the sbrk function */

#include

void malloc_init()

現在,為了完全地管理記憶體,我們需要能夠追蹤要分配和**哪些記憶體。在對記憶體塊進行了 free 呼叫之後,我們需要做的是諸如將它們標記為未被使用的等事情,並且,在呼叫 malloc 時,我們要能夠定位未被使用的記憶體塊。因此, malloc 返回的每塊記憶體的起始處首先要有這個結構:

複製**

//清單 3. 記憶體控制塊結構定義 [page]

struct mem_control_block ;

現在,您可能會認為當程式呼叫 malloc 時這會引發問題 —— 它們如何知道這個結構?答案是它們不必知道;在返回指標之前,我們會將其移動到這個結構之後,把它隱藏起來。這使得返回的指標指向沒有用於任何其他用途的記憶體。那樣,從呼叫程式的角度來看,它們所得到的全部是空閒的、開放的記憶體。然後,當通過 free() 將該指標傳遞回來時,我們只需要倒退幾個記憶體位元組就可以再次找到這個結構。

複製**

這就是我們的記憶體管理器。現在,我們只需要構建它,並在程式中使用它即可.多次呼叫malloc()後空閒記憶體被切成很多的小記憶體片段,這就使得使用者在申請記憶體使用時,由於找不到足夠大的記憶體空間,malloc()需要進行記憶體整理,使得函式的效能越來越低。聰明的程式設計師通過總是分配大小為2的冪的記憶體塊,而最大限度地降低潛在的malloc效能喪失。也就是說,所分配的記憶體塊大小為4位元組、8位元組、16位元組、18446744073709551616位元組,等等。這樣做最大限度地減少了進入空閒鏈的怪異片段(各種尺寸的小片段都有)的數量。儘管看起來這好像浪費了空間,但也容易看出浪費的空間永遠不會超過50%。

malloc函式 new和malloc的區別

1 申請的記憶體所在位置 new操作符從自由儲存區上為物件動態分配記憶體空間,而malloc函式從堆上動態分配記憶體。自由儲存區是c 基於new操作符的乙個抽象概念,凡是通過new操作符進行記憶體申請,該記憶體即為自由儲存區。而堆是作業系統中的術語,是作業系統所維護的一塊特殊記憶體,用於程式的記憶體...

malloc函式的問題

首先我們看看以下 include include include define size 0x40000 十六進製制的表示方法,等於十進位制262 144,你們要習慣用十六進製制,因為兩個十六進製制剛好是乙個位元組 int main 就是以上 你們使用vc和turbo c 分別編譯,看生成檔案的大小...

malloc 函式的使用

c語言中malloc是動態記憶體分配函式。函式原型 void malloc unsigned int num bytes 引數 num bytes 是無符號整型,用於表示分配的位元組數。返回值 如果分配成功則返回指向被分配記憶體的指標 此儲存區中的初始值不確定 否則返回空指標null。void 表示...