亚洲免费av电影一区二区三区,日韩爱爱视频,51精品视频一区二区三区,91视频爱爱,日韩欧美在线播放视频,中文字幕少妇AV,亚洲电影中文字幕,久久久久亚洲av成人网址,久久综合视频网站,国产在线不卡免费播放

        ?

        C++語言內(nèi)存分配研究

        2014-04-29 04:03:01張會
        計算機時代 2014年5期
        關(guān)鍵詞:編譯器鏈表指針

        張會

        摘 要: 詳細(xì)闡述了C++編譯器的內(nèi)存分配形式,給出了堆、棧、文字常量區(qū)、寄存器區(qū)、靜態(tài)區(qū)、程序代碼區(qū)的分配策略,分析了內(nèi)存分配中易產(chǎn)生的問題及導(dǎo)致程序運行出錯的原因和解決辦法,從而避免程序異常和內(nèi)存錯誤,保證程序的健壯性和正確性。

        關(guān)鍵詞: 內(nèi)存; 堆; 棧; C++語言

        中圖分類號:TP312 文獻(xiàn)標(biāo)志碼:A 文章編號:1006-8228(2014)05-44-03

        Abstract: The memory allocation strategy C++ compiler is described in detail in this paper. The distribution strategy of heap, stack, literals memory, register memory in C++ language is given. The causes and the solution of memory allocation problems and program running error are analyzed to avoid exception and memory errors, and guarantee the correctness and robustness of program.

        Key words: memory; heap; stack; C++ language

        0 引言

        C++編譯器根據(jù)數(shù)據(jù)在內(nèi)存中的生存期不同,將用戶使用的內(nèi)存分為程序區(qū)、靜態(tài)存儲區(qū)和動態(tài)存儲區(qū)三個區(qū)域,其中動態(tài)存儲區(qū)又分為堆區(qū)、棧區(qū)和寄存器區(qū)。

        1 內(nèi)存分配形式

        C++中內(nèi)存分配形式有以下六種。

        1.1 棧區(qū)(stack)

        棧由編譯器自動分配及釋放,用于存放函數(shù)參數(shù)值,局部變量值等。棧是一塊連續(xù)的內(nèi)存區(qū)域,它的大小為2M固定常數(shù),因此程序中的變量能從棧中獲取空間較少。若棧的剩余空間大于所申請空間,編譯器將為程序提供棧空間,且按照向低地址生長方向分配連續(xù)的內(nèi)存空間;若申請的空間超過棧的剩余空間,將報異常,提示棧溢出(overflow)[1]。

        在調(diào)用函數(shù)時,第一個進(jìn)棧的是被調(diào)用函數(shù)下一行的內(nèi)存地址,再是函數(shù)參數(shù),參數(shù)入棧的順序自右向左,再是函數(shù)的局部變量。函數(shù)調(diào)用結(jié)束后,首先出棧的是被調(diào)函數(shù)中的局部變量,再是參數(shù),次序是自左向右,所有變量和參數(shù)都出棧后,棧頂指針指到調(diào)用函數(shù)的下一行內(nèi)存地址,程序根據(jù)該地址跳轉(zhuǎn)到函數(shù)調(diào)用處的下一行自動執(zhí)行。入棧數(shù)據(jù)的內(nèi)存地址隨著入棧順序的先后向著內(nèi)存地址減小的方向增長,隨著數(shù)據(jù)不斷入棧,內(nèi)存地址不斷變小。由于棧的先進(jìn)后出原則,棧不會產(chǎn)生內(nèi)存碎片。雖然棧內(nèi)存小,但效率高,棧中存儲的數(shù)據(jù)只在函數(shù)內(nèi)有效,函數(shù)調(diào)用結(jié)束會因為數(shù)據(jù)出棧而被釋放。

        1.2 堆區(qū)(heap)

        堆內(nèi)存由程序員分配及釋放,若程序員在程序中未釋放,則在程序運行結(jié)束后,由操作系統(tǒng)回收。堆是不連續(xù)的空閑內(nèi)存區(qū)域,各塊區(qū)域由鏈表連接起來,其內(nèi)存大小由系統(tǒng)中虛擬內(nèi)存來確定,因此其空間較大,可以存放大量數(shù)據(jù)。

        堆區(qū)分配內(nèi)存空間時,系統(tǒng)會遍歷用于記錄內(nèi)存空閑塊的鏈表,首次找到一個空間大于所申請空間的堆結(jié)點時,將該結(jié)點從鏈表中刪除。并將該結(jié)點的內(nèi)存分配給程序,同時在這塊內(nèi)存區(qū)域首地址處記錄本次內(nèi)存分配大小,程序員在用delete或free釋放內(nèi)存時,以此識別要刪除內(nèi)存大小并正確刪除該段內(nèi)存。若申請的內(nèi)存空間與堆結(jié)點上的內(nèi)存空間不相等,則系統(tǒng)會自動將堆結(jié)點上多余內(nèi)存空間回收到空閑鏈表中。堆區(qū)在分配內(nèi)存時,鏈表中地址遍歷方向是由低向高,因此堆區(qū)分配內(nèi)存時是按照向高地址生長的方向分配不連續(xù)內(nèi)存空間[1]。堆內(nèi)存分配是由程序員進(jìn)行分配及釋放,速度較慢,易產(chǎn)生內(nèi)存碎片。

        堆是不連續(xù)的內(nèi)存區(qū)域,由鏈表將其串接起來的空閑塊,其不能像棧一樣可以為其中的某個存儲單元命名,堆中的每個內(nèi)存單元都是匿名的,對堆的訪問只能先在堆中申請內(nèi)存,再把申請內(nèi)存的首地址保存在一個指針中,再通過指針來訪問內(nèi)存。在C++中用malloc()和new關(guān)鍵字申請堆內(nèi)存。寄存器區(qū)一般用于保存棧頂指針和指令指針。

        1.4 靜態(tài)區(qū)(static)

        全局變量和靜態(tài)變量的存儲是放在一塊的,已初始化的全局變量和靜態(tài)變量放在一塊區(qū)域,未初始化的全局變量和靜態(tài)變量存放于相鄰的另一塊區(qū)域,內(nèi)存在程序結(jié)束后由系統(tǒng)釋放。靜態(tài)變量的空間在程序編譯階段進(jìn)行分配,所分配內(nèi)存在程序整個運行期間都存在[2]。

        1.6 程序代碼區(qū)

        存放函數(shù)體的二進(jìn)制代碼。

        2 內(nèi)存分配中若干問題的分析

        如果對內(nèi)存分配策略理解不清楚,且程序設(shè)計不當(dāng),就極易引起對運行結(jié)果異常,且難以捕獲由內(nèi)存分配所引起的錯誤。

        本程序的輸出結(jié)果既不是隨機值,也不是3而是4,是由??臻g的連續(xù)分配所引起。在main()函數(shù)中,首先調(diào)用fun()函數(shù),此時fun1()代碼行地址入棧,接著fun()中的局部變量x入棧,fun()調(diào)用結(jié)束后把x的內(nèi)存地址值返回給main()函數(shù)中的p指針,此時棧中的x已經(jīng)出棧。接著在main()中調(diào)用fun1()函數(shù),此時對fun1()中的a進(jìn)行棧內(nèi)存的分配,其分配的??臻g正好是fun()函數(shù)中x變量所釋放的內(nèi)存,對該內(nèi)存賦值4后,回到主函數(shù),此時??臻g的a變量內(nèi)存被釋放,而此時p指針從未改變,與此同時,程序沒有其他語句代碼或變量需要分配棧空間,因此p指針?biāo)傅臈?臻g的值未被覆蓋,保留最后一次所賦值4,故程序最后輸出的值是4。因此掌握了內(nèi)存中存儲空間的分配情況及原理,不難分析其異常的運行結(jié)果。

        為防止讓指向常量的指針對所指常量進(jìn)行值的改變,解決的辦法是把p聲明成常量指針,如:const char *p;以保證不能改變所指常量的值,若試圖通過指針改變常量的值,在編譯檢查時將報錯,不致于如上述程序段發(fā)生運行時錯誤。

        2.3 堆區(qū)內(nèi)存分配

        堆中的內(nèi)存是匿名的,對堆內(nèi)存進(jìn)行訪問只能通過指針進(jìn)行訪問。通過指針訪問堆內(nèi)存時,一定要注意防止內(nèi)存泄露。內(nèi)存泄露是指程序從堆中分配的內(nèi)存塊該內(nèi)存釋放后即存放了其他數(shù)據(jù),但p中的地址值仍然是所釋放那段內(nèi)存的地址值,因此第5行輸出*p的值是所釋放那段內(nèi)存中已存放的隨機值。第6行p1指向新申請的一段內(nèi)存,由于編譯器會默認(rèn)將釋放掉的內(nèi)存空間回收然后分配給新開辟的空間,因此第6行p1其實指向的是剛通p所釋放掉的空間3 內(nèi)存分配中存在的其他情況

        內(nèi)存分配發(fā)生的異常,編譯器不能通過語法檢查發(fā)現(xiàn),通常會發(fā)生程序運行結(jié)果異常,該類錯誤不易被捕捉,從而給程序員檢查程序錯誤帶來不便,因此在寫程序時盡量避免內(nèi)存分配錯誤。常見的內(nèi)存操作異常如下。

        ⑴ 內(nèi)存分配失敗卻直接使用,如返回一個NULL指針。

        ⑵ 訪問內(nèi)存時超出了內(nèi)存分配的邊界。越界的內(nèi)存可能保存其他變量的值,訪問該內(nèi)存變量的值,可能產(chǎn)生異常,導(dǎo)致程序的終止甚至崩潰[4]。

        ⑶ 動態(tài)申請了內(nèi)存空間如鏈表,而未動態(tài)釋放內(nèi)存空間,或未完全釋放,只釋放了鏈表中的表頭指針?biāo)赶蚪Y(jié)點,而未釋放鏈表中的各個結(jié)點的內(nèi)存空間,從而造成內(nèi)存泄露。

        (4)訪問已經(jīng)釋放的內(nèi)存,釋放已經(jīng)釋放的內(nèi)存。從而導(dǎo)致程序無法正確運行,得到無效值。

        4 結(jié)束語

        本文闡述了C++編譯器的內(nèi)存分配形式,提出了堆、棧、文字常量區(qū),寄存器區(qū)的分配策略,分析了內(nèi)存分配中易產(chǎn)生的問題和原因,同時給出了因內(nèi)存分配而導(dǎo)致程序錯誤的解決辦法,總之要解決程序中因內(nèi)存分配所產(chǎn)生的問題,其前提是必須要清楚內(nèi)存分配策略。通過本文對C++中內(nèi)存分配策略的研究,可以使讀者在以后的程序編寫中有效的避免內(nèi)存分配錯誤,從而保證程序的健壯性和正確性。

        參考文獻(xiàn):

        [1] 王文龍.C/C++數(shù)據(jù)內(nèi)存分配和指針使用中若干問題的分析[J].喀什

        師范學(xué)院學(xué)報,2013.34(6):36-37

        [2] 韓雨澇.C語言動態(tài)內(nèi)存分配研究及應(yīng)用[J].計算機時代,2009.5:

        33-34

        [3] 王金玲,柴萬東.C++動態(tài)內(nèi)存分配研究[J].赤峰學(xué)院學(xué)報,2009.25

        (4):19-20

        [4] Eri R.Hanly.C語言詳解[M].人民郵電出版社,2007.

        猜你喜歡
        編譯器鏈表指針
        基于相異編譯器的安全計算機平臺交叉編譯環(huán)境設(shè)計
        基于二進(jìn)制鏈表的粗糙集屬性約簡
        偷指針的人
        娃娃畫報(2019年5期)2019-06-17 16:58:10
        跟麥咭學(xué)編程
        基于鏈表多分支路徑樹的云存儲數(shù)據(jù)完整性驗證機制
        為什么表的指針都按照順時針方向轉(zhuǎn)動
        基于改進(jìn)Hough變換和BP網(wǎng)絡(luò)的指針儀表識別
        電測與儀表(2015年5期)2015-04-09 11:30:42
        鏈表方式集中器抄表的設(shè)計
        電測與儀表(2014年1期)2014-04-04 12:00:22
        ARM Cortex—MO/MO+單片機的指針變量替換方法
        通用NC代碼編譯器的設(shè)計與實現(xiàn)
        国产一区二区黄色录像| 人妻精品无码一区二区三区 | 极品少妇hdxx麻豆hdxx| 国内精品久久久久久久97牛牛| 国产超碰女人任你爽| 久久综合给合综合久久| 午夜精品久久久久成人| 午夜无码片在线观看影院| 国产精品流白浆喷水| 午夜影视啪啪免费体验区入口| 福利片免费 亚洲| 亚洲精品久久麻豆蜜桃| 男女动态91白浆视频| 国产在线视频91九色| 国产亚洲精品久久情侣| 国产午夜激无码av毛片不卡| 日韩av无码一区二区三区不卡| 正在播放国产多p交换视频 | 亚洲成av人片在线观看无码| 蜜臀av一区二区| 69堂在线无码视频2020| 国产三级三级精品久久| 日本免费视频一区二区三区| 国产自拍精品视频免费| 中文字幕日韩精品有码视频| 国产成人综合亚洲看片| 久久久久久亚洲精品中文字幕| 亚洲中文字幕无码久久2020| 久久久综合九色合综国产| 亚洲无码美韩综合| 丰满少妇被爽的高潮喷水呻吟| 中国一级黄色片久久久| 无码人妻h动漫中文字幕| 亚洲综合色区另类av| 日日碰狠狠躁久久躁96avv| 久久国产国内精品对话对白| 久久精品国产亚洲av热九九热| 麻豆成年人视频在线观看| 美女视频一区二区三区在线 | 日韩av最新在线地址| 深夜一区二区三区视频在线观看|