|
ezikra3xgf464093973227.gif (60.41 KB, 下載次數(shù): 0)
下載附件
保存到相冊(cè)
ezikra3xgf464093973227.gif
2024-11-5 21:36 上傳
點(diǎn)擊上方藍(lán)色字體,關(guān)注我們
以下是我的一些看法。
malloc 和 free 實(shí)際上是依賴于 C 庫(kù)和操作系統(tǒng)提供的內(nèi)存管理機(jī)制,它們基于特定的數(shù)據(jù)結(jié)構(gòu)和算法來(lái)管理動(dòng)態(tài)分配的內(nèi)存。
1
malloc 內(nèi)存分配的實(shí)現(xiàn)
當(dāng)你調(diào)用 malloc 分配內(nèi)存時(shí),C 運(yùn)行時(shí)庫(kù)(如 glibc)會(huì)從堆中分配一塊內(nèi)存。在這個(gè)過(guò)程中,分配器會(huì)維護(hù)一個(gè)內(nèi)部的 “自由鏈表”(free list)或其他數(shù)據(jù)結(jié)構(gòu)來(lái)追蹤哪些內(nèi)存塊是空閑的,哪些是已分配的。
當(dāng)需要分配內(nèi)存時(shí),分配器會(huì)從自由鏈表中找到合適大小的空閑塊,然后將這塊內(nèi)存返回,并在鏈表中更新其狀態(tài)。
2
free 釋放內(nèi)存的原理
在 free 時(shí),分配器需要知道內(nèi)存塊的起始地址以及它的大小,以便將其標(biāo)記為空閑并重新加入自由鏈表。你提到的“如何知道要釋放的內(nèi)存大小”是一個(gè)關(guān)鍵問(wèn)題,這確實(shí)依賴于內(nèi)存分配器內(nèi)部的數(shù)據(jù)結(jié)構(gòu)。
通常分配器會(huì)在每個(gè)分配的內(nèi)存塊前增加一個(gè) “頭部”(header),這個(gè)頭部存儲(chǔ)了該內(nèi)存塊的元信息,包括分配的大小和狀態(tài)(空閑或已分配)。因此,當(dāng)你傳遞指針 p 給 free 時(shí),分配器可以通過(guò) p 之前的頭部信息找到整個(gè)塊的大小,然后正確釋放該塊。
3
為什么 free(p + 6) 仍然能釋放整個(gè)塊
在 C 中,標(biāo)準(zhǔn)庫(kù)實(shí)現(xiàn)中并不支持直接釋放偏移后的地址(如 p + 6)。嘗試調(diào)用 free(p + 6) 實(shí)際上會(huì)導(dǎo)致未定義行為,具體表現(xiàn)取決于實(shí)現(xiàn),但通常會(huì)導(dǎo)致程序崩潰或產(chǎn)生錯(cuò)誤。
4
數(shù)據(jù)結(jié)構(gòu)和性能優(yōu)化
典型的內(nèi)存分配器使用 雙向鏈表 或 分離鏈表 來(lái)維護(hù)空閑和已分配的內(nèi)存塊,以便快速找到和釋放內(nèi)存。自由鏈表通常按大小分段存儲(chǔ),以便在釋放時(shí)找到最合適的塊,減少碎片化。
在一些高級(jí)分配器(如 tcmalloc 或 jemalloc)中,使用了更加復(fù)雜的數(shù)據(jù)結(jié)構(gòu),例如 哈希表或樹狀結(jié)構(gòu)(如紅黑樹)來(lái)管理和分配內(nèi)存。這種結(jié)構(gòu)優(yōu)化了查找速度,并通過(guò)不同大小的塊分區(qū)降低了碎片化程度。
yq0nci3fyq264093973327.jpg (71.14 KB, 下載次數(shù): 0)
下載附件
保存到相冊(cè)
yq0nci3fyq264093973327.jpg
2024-11-5 21:36 上傳
rhxkbiwolze64093973427.gif (45.46 KB, 下載次數(shù): 0)
下載附件
保存到相冊(cè)
rhxkbiwolze64093973427.gif
2024-11-5 21:36 上傳
點(diǎn)擊閱讀原文,更精彩~ |
|