還是要認真看深入理解電腦系統
http://blog.csdn.net/llhyy17/article/details/5375298
記憶體配置是按照堆塊實現的,一個堆塊是由頭部和有效載荷量組成,其中的有效載荷量就是我們申請的堆的大小。
頭部塊包括 塊大小和是否可用 這兩個部分組成。
在記憶體中這些堆塊以鏈表形勢組成
malloc函數的實質體現在,它有一個將可用的記憶體塊串連為一個長長的列表的所謂空閑鏈表。調用malloc函數時,它沿串連表尋找一個大到足以滿足使用者請求所需要的記憶體塊。然後,將該記憶體塊一分為二(一塊的大小與使用者請求的大小相等,另一塊的大小就是剩下的位元組)。接下來,將分配給使用者的那塊記憶體傳給使用者,並將剩下的那塊(如果有的話)返回到串連表上。調用free函數時,它將使用者釋放的記憶體塊串連到空閑鏈上。到最後,空閑鏈會被切成很多的小記憶體片段,如果這時使用者申請一個大的記憶體片段,那麼空閑鏈上可能沒有可以滿足使用者要求的片段了。於是,malloc函數請求延時,並開始在空閑鏈上翻箱倒櫃地檢查各記憶體片段,對它們進行整理,將相鄰的小空閑塊合并成較大的記憶體塊。
在對記憶體塊進行了 free 調用之後,我們需要做的是諸如將它們標記為未被使用的等事情,並且,在調用 malloc 時,我們要能夠定位未被使用的記憶體塊。因此, malloc返回的每塊記憶體的起始處首先要有這個結構:
//清單 3. 記憶體控制塊結構定義
struct mem_control_block {
int is_available;
int size;
};
現在,您可能會認為當程式調用 malloc 時這會引發問題 —— 它們如何知道這個結構?答案是它們不必知道;在返回指標之前,我們會將其移動到這個結構之後,把它隱藏起來。這使得返回的指標指向沒有用於任何其他用途的記憶體。那樣,從調用程式的角度來看,它們所得到的全部是閒置、開放的記憶體。然後,當通過 free() 將該指標傳遞迴來時,我們只需要倒退幾個記憶體位元組就可以再次找到這個結構。
在討論分配記憶體之前,我們將先討論釋放,因為它更簡單。為了釋放記憶體,我們必須要做的惟一一件事情就是,獲得我們給出的指標,回退 sizeof(struct mem_control_block) 個位元組,並將其標記為可用的。這裡是對應的代碼:
清單 4. 解除配置函數
void free(void *firstbyte) {
struct mem_control_block *mcb;
/* Backup from the given pointer to find the
* mem_control_block
*/
mcb = firstbyte - sizeof(struct mem_control_block);
/* Mark the block as being available */
mcb->is_available = 1;
/* That''s It! We''re done. */
return;
}
如您所見,在這個分配程式中,記憶體的釋放使用了一個非常簡單的機制,在固定時間內完成記憶體釋放。