c語言動態(tài)內(nèi)存分配的優(yōu)缺點(diǎn)及注意事項
在大多數(shù)常見情況下,C語言編譯程序會將靜態(tài)變量和全局變量采用靜態(tài)內(nèi)存分配。這些能夠確定大小的內(nèi)存會在程序啟動時分配好,大多數(shù)會存在于一個抽象的概念“堆”當(dāng)中。而確定長度的局部變量則會在函數(shù)被調(diào)用時在棧中預(yù)分配,隨著函數(shù)的返回和超過其作用域時被“銷毀”。
然而,在一些情況下,需要動態(tài)地申請內(nèi)存,比如動態(tài)鏈表,因為鏈表的長度是不確定的。為了提高內(nèi)存利用率,需要提供一個函數(shù)向操作系統(tǒng)、內(nèi)存池或其他地方申請內(nèi)存,申請多少使用多少,不再需要時將內(nèi)存釋放歸還。
通常使用malloc函數(shù)申請的內(nèi)存存在于堆中,而通過非標(biāo)準(zhǔn)拓展vla分配的內(nèi)存大概率存在于棧中(部分實(shí)現(xiàn)也在堆里)。
然而,動態(tài)分配內(nèi)存并不完美。首先,從邏輯實(shí)現(xiàn)來說,動態(tài)內(nèi)存分配需要一個內(nèi)存管理程序,記錄內(nèi)存的分配大小、釋放節(jié)點(diǎn)、空余節(jié)點(diǎn),甚至添加一堆調(diào)試信息,這些操作需要額外占用內(nèi)存,因此,實(shí)際使用的物理內(nèi)存會大于申請的內(nèi)存空間。其次,頻繁的不同長度的動態(tài)內(nèi)存分配與釋放可能造成內(nèi)存碎片。例如,將一連串100字節(jié)內(nèi)存分配出去,其中一塊內(nèi)存被釋放了,然后又申請99字節(jié)內(nèi)存。于是,有一個1字節(jié)內(nèi)存夾在一大片連續(xù)內(nèi)存中,因為太小而得不到充足的利用。當(dāng)這種離散零碎的小空間越來越多時,就會導(dǎo)致越來越多的碎片內(nèi)存因無法利用而浪費(fèi)。因此,為了避免這種情況,往往會對申請內(nèi)存進(jìn)行對齊,實(shí)際分配內(nèi)存大小會大于申請內(nèi)存大小,從而增加內(nèi)存利用率。
另外,現(xiàn)代操作系統(tǒng)中,為了物理內(nèi)存的利用率、安全性和復(fù)用性,會結(jié)合硬件支持對內(nèi)存進(jìn)行段式、頁式或段頁式管理。在這種分配機(jī)制中,極端情況下,即使僅使用1字節(jié)內(nèi)存,也可能占據(jù)整頁內(nèi)存,導(dǎo)致頁內(nèi)其他內(nèi)存得不到利用而浪費(fèi)。
剛好,我這里有C語言資料包,私信我領(lǐng)取