malloc和free的實現原理

2021-07-12 02:20:56 字數 1889 閱讀 9744

對於malloc來說,很多人都不陌生。然而,我們對它的了解並不是很深,我們常常會用,而不明白其中的原理,從而,很容易造成記憶體洩漏,記憶體碎片等問題。這常常讓我們頭痛不已,故而我們需要進一步的去了解它。

首先,什麼事malloc?

在很多人認為malloc是個關鍵字,但是malloc只是c的標準庫中提供的乙個普通函式。

malloc 向系統申請分配指定size個位元組的記憶體空間,返回型別是 void* 型別。

它的返回值是如果分配成功則返回指向被分配記憶體的指標(此儲存區中的初始值不確定),否則返回空指標null。當記憶體不再使用時,應使用free()函式將記憶體塊釋放。

我們看看其原始碼是如何寫的

void * __cdecl _malloc_base (size_t size)

if (_newmode == 0)

//  call installed new handler

if (!_callnewh(size))

break;

//  new handler was successful -- try to allocate again

}} else 

rtccallback(_rtc_allocate_hook, (res, size, 0));

if (res == null)

return res;

}

這是vs2012中malloc的原始碼,我們可見其如何實現的,接下來我們看看free的源**

void __cdecl _free_base (void * pblock)

}

關於記憶體方面在《unix環境高階程式設計》中第七章的一段話,是這樣說的:

大多數實現所分配的儲存空間比所要求的要稍大一些,額外的空間用來記錄管理資訊——分配塊的長度,指向下乙個分配塊的指標等等。這就意味著如果寫過乙個已分配區的尾端,則會改寫後一塊的管理資訊。這種型別的錯誤是災難性的,但是因為這種錯誤不會很快就暴露出來,所以也就很難發現。將指向分配塊的指標向後移動也可能會改寫本塊的管理資訊。

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

glibc維護了不止乙個不定長的記憶體塊鍊錶,而是好幾個,每乙個這種鍊錶負責乙個大小範圍,這種做法有效減少了分配大記憶體時的遍歷開銷,類似於雜湊的方式,將很大的範圍的資料雜湊到有限的幾個小的範圍內而不是所有資料都放在一起,雖然最終還是要在小的範圍內查詢,但是最起碼省去了很多的開銷,如果只有乙個不定長鍊表那麼就要全部遍歷,如果分成3個,就省去了2/3的開銷,總之這個策略十分類似於雜湊。glibc另外的策略就是不止維護一類空閒鍊錶,而是另外再維護乙個緩衝鍊錶和乙個高速緩衝鍊錶,在分配的時候首先在快取記憶體中查詢,失敗之後再在空閒鍊錶查詢,如果找到的記憶體塊比較大,那麼將切割之後的剩餘記憶體塊插入到快取鍊錶,如果空閒鍊錶查詢失敗那麼就往快取鍊錶中查詢. 如果還是沒有合適的空閒塊,就向記憶體申請比請求數更大的記憶體塊,然後把剩下的記憶體放入鍊錶中。

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

這就解釋了,為什麼在程式中free之後,但是堆的記憶體還是沒有釋放。

malloc和free的實現

被人問到malloc和free的實現問題。我們知道malloc的呼叫形式如 type p type malloc n sizeof type free的呼叫形式如 free p 好了,問題來了,free函式,我們只給傳入乙個指標,沒有傳入記憶體塊的大小n,那麼編譯器怎麼知道要釋放多少位元組的記憶體,...

malloc和free的區別

1,malloc與free是c c語言的標準庫函式,new delete是c 的運算子。它們都可用於申請動態記憶體和釋放記憶體。2,對於非內部資料型別的物件而言,光用maloc free無法滿足動態物件的要求。物件在建立的同時要自動執行建構函式,物件在消亡之前要自動執行析構函式。由於malloc f...

C語言malloc和free實現原理

以下是一段簡單的c malloc和free到底做了什麼?int main malloc和free的debug和release版本實現各不相同,而且相差很大。malloc需要分配的記憶體會比實際的size多36byte。最終分配的記憶體塊如下 crtmemblockheader是乙個雙向鍊錶結構,其定...