程序在編譯、運(yùn)行等各個(gè)過(guò)程中,不同性質(zhì)的數(shù)據(jù)存放在不同的位置。動(dòng)態(tài)內(nèi)存是從堆上分配,也叫動(dòng)態(tài)內(nèi)存分配。程序員自己負(fù)責(zé)在何時(shí)釋放內(nèi)存。動(dòng)態(tài)內(nèi)存的生存期由程序員決定,使用非常靈活。 1.從靜態(tài)存儲(chǔ)區(qū)域分配 內(nèi)存在程序編譯時(shí)就已經(jīng)分配好,這塊內(nèi)存在程序的整個(gè)運(yùn)行期間都存在。速度快、不容易出錯(cuò),因?yàn)橛邢到y(tǒng)會(huì)善后。例如全局變量,static變量等。 2.在棧上分配 在執(zhí)行函數(shù)時(shí),函數(shù)內(nèi)局部變量的存儲(chǔ)單元都在棧上創(chuàng)建,函數(shù)執(zhí)行結(jié)束時(shí)這些存儲(chǔ)單元自動(dòng)被釋放。棧內(nèi)存分配運(yùn)算內(nèi)置于處理器的指令集中,效率很高,但是分配的內(nèi)存容量有限。 3.從堆上分配 即動(dòng)態(tài)內(nèi)存分配。程序在運(yùn)行的時(shí)候用malloc或new申請(qǐng)任意大小的內(nèi)存,程序員自己負(fù)責(zé)在何時(shí)用free或delete釋放內(nèi)存。動(dòng)態(tài)內(nèi)存的生存期由程序員決定,使用非常靈活。如果在堆上分配了空間,就有責(zé)任回收它,否則運(yùn)行的程序會(huì)出現(xiàn)內(nèi)存泄漏,另外頻繁地分配和釋放不同大小的堆空間將會(huì)產(chǎn)生堆內(nèi)碎塊。 一個(gè)C、C++程序編譯時(shí)內(nèi)存分為5大存儲(chǔ)區(qū):堆區(qū)、棧區(qū)、全局區(qū)、文字常量區(qū)、程序代碼區(qū),如下表所示。 實(shí)例: 補(bǔ)充:在不同的內(nèi)存區(qū)域,對(duì)于理解編程中的數(shù)據(jù)類型作用域和注意事項(xiàng),比如靜態(tài)數(shù)據(jù)和全局?jǐn)?shù)據(jù)對(duì)其聲明后區(qū)域的全局可見性,動(dòng)態(tài)申請(qǐng)的內(nèi)存為什么要及時(shí)釋放等有很大的幫助。 代碼段1 代碼段2 代碼段3 代碼段4 分析問題:代碼一到代碼四主要考查面試者對(duì)內(nèi)存操作的理解程度,基本功扎實(shí)的面試者能找到大部分的錯(cuò)誤,但是全部找出還是有一定難度的。這四段代碼主要有以下三個(gè)問題: 代碼一:傳入函數(shù)A( char *p )的參數(shù)為字符型指針,在這個(gè)函數(shù)修改參數(shù)p的值時(shí)并不能真正修改實(shí)參的值,如: 執(zhí)行完這兩句后str的值仍然是NULL,如果想改變指針的值,就得用二階指針來(lái)完成。不理解指針和指針的用法是導(dǎo)致這個(gè)錯(cuò)誤的主要原因。 代碼二:在函數(shù)A(void )中: 其中的p[]數(shù)組是函數(shù)A中的局部變量,函數(shù)返回后,p就被釋放掉了,str指向了一段無(wú)用的內(nèi)存區(qū)域,輸出的str會(huì)是亂碼。理解變量的作用域是解決本題的關(guān)鍵。 代碼三:避免了代碼一中的問題,A的參數(shù)是二階指針,傳入的參數(shù)也是字符串的指針的指針,這樣就可以在函數(shù)A中改變字符串指針的值了。但是在A中執(zhí)行了申請(qǐng)動(dòng)態(tài)內(nèi)存的并且賦值給字符串指針的語(yǔ)句: 在Test中A返回后,沒有對(duì)指針*p做任何判斷就使用了p。 假如動(dòng)態(tài)內(nèi)存沒有申請(qǐng)成功,這句就會(huì)出現(xiàn)錯(cuò)誤,所以在申請(qǐng)動(dòng)態(tài)內(nèi)存后,應(yīng)該首先判斷是內(nèi)存否申請(qǐng)成功,然后再使用,以避免錯(cuò)誤發(fā)生。如下: 另外,沒有釋放動(dòng)態(tài)申請(qǐng)的內(nèi)存空間。 代碼四:同代碼三一樣,申請(qǐng)了動(dòng)態(tài)內(nèi)存后沒有檢驗(yàn)是否申請(qǐng)成功就直接使用,并且在free( str)后str沒有置空,str成了“野指針”。一定要記得每次釋放動(dòng)態(tài)申請(qǐng)的內(nèi)存空間后指針要置空,如下: 四段代碼全有錯(cuò)誤: 注意:申請(qǐng)動(dòng)態(tài)內(nèi)存時(shí)一定要先判斷是否申請(qǐng)成功,失敗時(shí)要進(jìn)行失敗處理;動(dòng)態(tài)內(nèi)存使用后要及時(shí)釋放,不要造成內(nèi)存的泄漏;釋放后將原先指向動(dòng)態(tài)內(nèi)存的指針置空,以免生成“野指針”。 |
|
來(lái)自: C語(yǔ)言與CPP編程 > 《待分類》