2010-08-09 29 views

回答

2

OS將不會有一個線索,免費不是一個系統調用。但是,當內存最初由malloc()分配時,您的C庫內存分配系統會以某種方式記錄大小,因此它知道要釋放多少內存。

0

大小在內部存儲在分配器中,並且您傳遞給空閒的指針用於到達該數據。一個非常基本的方法是在指針之前存儲4個字節的大小,因此從指針中減去4會給你一個指向它的大小的指針。

請注意,操作系統不直接處理它,它是由您的C/C++運行時分配器實現的。

0

當您調用malloc時,C庫會自動在堆上爲您劃出空間。因爲在堆上創建的東西是動態創建的,所以在任何給定時間點上堆中的內容都不知道,因爲它是用於堆棧的。所以圖書館會跟蹤你在堆上分配的所有內存。

在某些時候,你的堆可能是這樣的:

   p---+ 
        V 
    --------------------------------------- 
... | used (4) | used (10) | used (8) | ... 
    --------------------------------------- 

圖書館將跟蹤了多少內存分配給每個塊。在這種情況下,指針p指向中間塊的開始。

如果我們做以下電話:

free(p); 

那麼庫將釋放此空間,讓您在堆上,像這樣......

   p---+ 
        V 
    ---------------------------------------- 
... | used (4) | unused(10) | used (8) | ... 
    ---------------------------------------- 

現在,下一次你正在尋找一些空間,如打電話說:

void* ptr = malloc(10); 

新近未使用的空間可能會分配給您的程序再次,這將允許我們減少程序使用的內存總量。

  ptr---+ 
        V 
    ---------------------------------------- 
... | used (4) | used(10) | used (8) | ... 
    ---------------------------------------- 

您的圖書館可能在內部管理尺寸的方式有所不同。實現這一點的一個簡單方法是在分配每個塊的開始處添加額外的字節數(在本例中爲1),以保存每個塊的大小。所以,我們以前的堆內存塊應該是這樣的:

bytes: 1 4 1 10 1 8 
    -------------------------------- 
... |4| used |10| used |8| used | ... 
    -------------------------------- 
       ^
        +---ptr 

現在,如果我們說,塊大小將四捨五入由2整除,他們都得在大小結束一個額外位(因爲我們總是可以假定它爲0,我們可以方便地使用,查看相應塊是否已使用或未使用

當我們在自由傳遞一個指針:

free(ptr); 

圖書館將移動指針返回一個字節,並將已使用/未使用的位更改爲未使用我們甚至不必真正知道塊的大小以釋放它。當我們嘗試重新分配相同數量的數據時,它只會成爲一個問題。然後,malloc調用將沿線,檢查下一個塊是否空閒。如果它是空閒的,那麼如果這個塊的大小正確的話會返回給用戶,否則一個新的塊將在堆的末尾被切斷,並且如果需要的話從OS分配更多的空間。

+0

一些實施並不將大小存儲爲它分配的塊的一部分,而是將存儲器地址用作存儲大小的內部數據結構的索引。 – nos 2010-08-09 16:20:17

+0

@nos誠然,但我想我說這只是一個簡單的方法,你可以實現它。如果我沒有,那麼我的意思是。 – KLee1 2010-08-09 16:30:03

相關問題