欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

全局靜態(tài)存儲(chǔ)區(qū)、堆區(qū)和棧區(qū)深入剖析

 更新時(shí)間:2012年11月12日 11:41:16   作者:  
在C++中,內(nèi)存可分為系統(tǒng)數(shù)據(jù)區(qū),自由存儲(chǔ)區(qū),文本區(qū),const數(shù)據(jù)區(qū),全局靜態(tài)區(qū),堆區(qū)和棧區(qū)
在C++中,內(nèi)存可分為系統(tǒng)數(shù)據(jù)區(qū),自由存儲(chǔ)區(qū),文本區(qū),const數(shù)據(jù)區(qū),全局靜態(tài)區(qū),堆區(qū)和棧區(qū)。其中,系統(tǒng)數(shù)據(jù)區(qū)存放的是系統(tǒng)數(shù)據(jù),我們是不能自由訪問(wèn)的,有時(shí)候windows系統(tǒng)會(huì)突然彈出一個(gè)消息框,內(nèi)容是“內(nèi)存不能為read”就是錯(cuò)誤訪問(wèn)系統(tǒng)數(shù)據(jù)區(qū)的結(jié)果;自由存儲(chǔ)區(qū)用來(lái)存放由C延伸而來(lái)的malloc()函數(shù)所分配的數(shù)據(jù);文本區(qū)存放著我們的函數(shù)代碼,我們調(diào)用函數(shù)時(shí)的底層行為就類(lèi)似于先去操作一個(gè)指針,而這個(gè)指針就指向函數(shù)指令所在的地址,也就是在文本區(qū)中;const數(shù)據(jù)區(qū),顧名思義,就是存放不可修改的數(shù)據(jù)的內(nèi)存區(qū)域,我們定義的const變量都存放在這里。最后,我們來(lái)看全局靜態(tài)存儲(chǔ)區(qū)、堆區(qū)和棧區(qū)。

先來(lái)看全局靜態(tài)存儲(chǔ)區(qū),在程序中,由static標(biāo)號(hào)定義的數(shù)據(jù)都存放在全局靜態(tài)存儲(chǔ)區(qū)中,不論是在main()函數(shù)之外的定義的全局變量,還是在子函數(shù)中定義的局部變量,只要在定義之前有static標(biāo)號(hào),定義之后就會(huì)始終存在于全局靜態(tài)存儲(chǔ)區(qū)中。當(dāng)然,在main()函數(shù)之外定義的全局靜態(tài)變量在任何地方都可以訪問(wèn),而在子函數(shù)中定義的局部靜態(tài)變量只有在定義該變量的模塊中可見(jiàn)。但是也存在這樣一種現(xiàn)象:如前邊所述,即使在子函數(shù)中定義的局部靜態(tài)變量,其存在形式也是靜態(tài)的,也就是說(shuō),只要在變量定義的語(yǔ)句執(zhí)行之后,即使在變量不可見(jiàn)的地方,只要對(duì)該變量所在的地址取地址解析操作,也是可以獲得該變量的值的。比如我們?cè)诤瘮?shù)fun()中定義了一個(gè)static int a=100;假設(shè)該變量的地址是0x0042AD54,我們?cè)趍ain()函數(shù)中調(diào)用fun()之后,如果對(duì)0x0042AD54取地址解析,也是可以得到100的:int* p=(int*)0x0042ad54; int b=*p;這里b被賦值100。由此,我們可以看到,凡是有static定義的變量的生命周期就是整個(gè)程序的生命周期,直到程序退出,靜態(tài)變量所占據(jù)的內(nèi)存才會(huì)被釋放。

堆存儲(chǔ)區(qū)的行為類(lèi)似于靜態(tài)存儲(chǔ)區(qū),當(dāng)我們?cè)诙焉戏峙鋬?nèi)存之后,如果不進(jìn)行手動(dòng)的釋放,其內(nèi)存是不會(huì)自動(dòng)釋放掉的。但是在JAVA中,有一種叫做垃圾清理的機(jī)制可以自動(dòng)清理堆內(nèi)存,但是在C++中沒(méi)有這樣的機(jī)制。也就是說(shuō),在C++中,如果我們分配了堆內(nèi)存,就必須手動(dòng)釋放它。否則如果我們不停的分配堆內(nèi)存,但是不對(duì)其進(jìn)行釋放,當(dāng)對(duì)內(nèi)存被耗盡是就會(huì)造成程序崩潰。

一般地,用new分配的變量是存放于堆內(nèi)存中的,但是返回的指針變量是存放在棧中的。當(dāng)我們?cè)谝粋€(gè)子函數(shù)中new了一個(gè)變量,但是在函數(shù)返回時(shí)既沒(méi)有保存new返回的指針,也沒(méi)有delete時(shí),就會(huì)造成內(nèi)存泄露。如果我們寫(xiě)的是服務(wù)器程序,不斷地內(nèi)存泄露所造成的最終結(jié)果就是服務(wù)器死機(jī)。但是在windows、linux以及其他一些成熟的系統(tǒng)中,都有類(lèi)似于內(nèi)存保護(hù)的機(jī)制。系統(tǒng)會(huì)給用戶(hù)程序分配一定的運(yùn)行所需的內(nèi)存,同是也會(huì)給系統(tǒng)自身的運(yùn)行保留一部分內(nèi)存,這部分內(nèi)存是用戶(hù)程序所不能訪問(wèn)的。如果我們編寫(xiě)的程序存在內(nèi)存泄露,當(dāng)耗盡系統(tǒng)給應(yīng)用程序分配的內(nèi)存之后,程序就會(huì)停止運(yùn)行,而不會(huì)造成系統(tǒng)的司機(jī)。

至于棧內(nèi)存,也是我們?cè)趯?xiě)程序中用到的最多的情況。程序中定義的每一個(gè)臨時(shí)對(duì)象,new所返回的指針,以及遞歸函數(shù)中變量都是存放在棧中的。棧內(nèi)存是可以自動(dòng)釋放的,當(dāng)我們?cè)谀硞€(gè)模塊中定義了一個(gè)對(duì)象,在該模塊結(jié)束時(shí),變量所占據(jù)的內(nèi)存就會(huì)被系統(tǒng)回收,在定義新的變量時(shí),新的變量就有可能存放在原變量所在的地址上,但是在系統(tǒng)回收棧內(nèi)存的時(shí)候,是不會(huì)清空所釋放的棧內(nèi)存中的數(shù)據(jù)的,只是將棧頂重新調(diào)整,并在新數(shù)據(jù)的到來(lái)時(shí)將其分配到棧頂。

在C++中,雖然可以自由操作內(nèi)存,但這種技術(shù)就像是一把雙刃劍,用好了鋒利無(wú)比,用不好反而會(huì)造成一些自己都不能理解的莫名其妙的結(jié)果。深入理解內(nèi)存的分配方式,對(duì)于實(shí)際編程是大有助益的。

相關(guān)文章

最新評(píng)論