freepeople性欧美熟妇, 色戒完整版无删减158分钟hd, 无码精品国产vα在线观看DVD, 丰满少妇伦精品无码专区在线观看,艾栗栗与纹身男宾馆3p50分钟,国产AV片在线观看,黑人与美女高潮,18岁女RAPPERDISSSUBS,国产手机在机看影片

正文內(nèi)容

初探j(luò)ava內(nèi)存機(jī)制_堆和棧(編輯修改稿)

2024-10-14 01:14 本頁(yè)面
 

【文章內(nèi)容簡(jiǎn)介】 題,具體詳見“操作系統(tǒng)”的有關(guān)知識(shí)。,其棧頂指針從棧底地址開始,逐漸向低地址走。也就是說棧的存儲(chǔ)空間是從高地址走向低地址的。堆則相反,堆在申請(qǐng)空間的時(shí)候通常逐漸往高地址的方向來尋找可用內(nèi)存。純粹的文字描述顯得枯燥無味,我們來看一些代碼:[cpp] view plaincopyprint?include using namespace std。void func(){int i = 5。int j = 3。int k = 7。int *p = amp。i。printf(“%dn”, *p)。printf(“%dn”, *(p1))。printf(“%dn”, *(p2))。}int main(){func()。getchar()。return 0。}上述代碼的結(jié)果是:5 3 7從結(jié)果中我們可以看出兩件事:一是棧地址是連續(xù)的,我們可以通過一個(gè)指針和一個(gè)相對(duì)的大小,來“偏移”到別的變量上去。二是從中可以看出棧地址是從高到低分布的,棧底在高地址,朝低地址的方向生長(zhǎng)。所以程序中是p1而不是p+1。[cpp] view plaincopyprint?void func(){int *p = NULL。// 上行代碼是個(gè)重點(diǎn)。這個(gè)指針待會(huì)會(huì)用于申請(qǐng)新的內(nèi)存。// 此時(shí)除了它自身作為一個(gè)變量需要占用4字節(jié)的空間(指針都占4字節(jié)),沒有任何其他空間被申請(qǐng)。// 這個(gè)指針變量是函數(shù)的局部變量,所以它被創(chuàng)建在棧上。int num = 100。// 這個(gè)變量同樣創(chuàng)建于棧上。int buffer[100]。// 同樣的,buffer占用了棧的400字節(jié)的空間p = new int[100]。// 注意,程序員手動(dòng)申請(qǐng)了一塊空間,這400字節(jié)的內(nèi)存創(chuàng)建于堆上。// 所以此刻p的狀態(tài)是:p為函數(shù)局部變量,它指向了一塊全局范圍的內(nèi)存空間。}// 函數(shù)體結(jié)束。上述函數(shù)有個(gè)嚴(yán)重的問題,那就是指針p的內(nèi)存泄露。// 正確的做法是在函數(shù)最后delete掉這塊內(nèi)存,或是返回這塊內(nèi)存的地址以供繼續(xù)使用。接下來我們來了解一下當(dāng)調(diào)用一個(gè)函數(shù)的時(shí)候所發(fā)生的事情:首先操作系統(tǒng)為這個(gè)函數(shù)分配了一個(gè)棧,因?yàn)樵谡{(diào)用完這個(gè)函數(shù)以后需要能正確返回到下一條語句并繼續(xù)執(zhí)行,所以第一步是將調(diào)用完函數(shù)的下一條指令的地址壓入棧。這樣當(dāng)函數(shù)調(diào)用完成,棧頂指針一點(diǎn)點(diǎn)釋放內(nèi)存以后,棧頂指針指向了這個(gè)地址,就能返回到正確的位置繼續(xù)執(zhí)行了。[cpp] view plaincopyprint?int main(){func()。printf(“%dn”, 100)。return 0。}比如上述代碼,在調(diào)用func之前,首先把func的下一條語句,也就是printf語句的地址,存在棧中。這樣函數(shù)調(diào)用完成后就能正確返回到這個(gè)printf并繼續(xù)往后執(zhí)行了。注意這里的地址是指令地址,而不是變量地址什么的。它有那么點(diǎn)類似于操作系統(tǒng)中的程序計(jì)數(shù)器(PC,即Program Counter)。然后把實(shí)參從右到左的順序依次入棧(大多數(shù)的C/C++編譯器為從右到左)接著是函數(shù)中的各種局部變量。要注意的是函數(shù)中的static變量是不入棧的。全局變量和static變量在編譯的時(shí)候就已經(jīng)在靜態(tài)存儲(chǔ)區(qū)分配好內(nèi)存了。如果這個(gè)時(shí)候該函數(shù)又調(diào)用了其它函數(shù),過程也是一樣的,首先是返回地址,然后是參數(shù)和局部變量。這樣在每層調(diào)用結(jié)束,棧頂指針不斷下降(釋放內(nèi)存)的時(shí)候,就能正確返回到之前調(diào)用的位置并繼續(xù)往下執(zhí)行了。出棧,或者說釋放內(nèi)存的過程,根據(jù)棧的特性,是相反的,所以就不贅述了。一個(gè) C或C++程序,它眼中的內(nèi)存地址分分為這么五個(gè)區(qū)域:棧區(qū)(stack)、堆區(qū)(heap)、全局靜態(tài)區(qū)(static)、文字常量區(qū)和程序指令區(qū)。棧區(qū)和堆區(qū)前面已經(jīng)介紹過,全局靜態(tài)區(qū)用于存放全局變量和靜態(tài)static靜態(tài)變量,全局靜態(tài)區(qū)分為兩塊內(nèi)容:一塊用于初始化以后的全局變量和靜態(tài)變量,一塊用于未初始化的全局變量和靜態(tài)變量。全局靜態(tài)區(qū)和堆一樣,程序結(jié)束后由操作系統(tǒng)進(jìn)行釋放。文字常量區(qū)用于存放常量字符串,程序結(jié)束后由操作系統(tǒng)進(jìn)行釋放。程序指令區(qū)最好理解,就是存放程序代碼的二進(jìn)制指令。[cpp] view plaincopyprint?int t。// 存放在全局靜態(tài)區(qū)的未初始化區(qū)int num = 0。// 存放在全局靜態(tài)區(qū)的已初始化區(qū)int *p。// 存放在全局靜態(tài)區(qū)的未初始化區(qū)int main(){int i, j, k。// 存放在棧區(qū)int *pBuffer =(int *)malloc(sizeof(int)* 10)。// 指針pBuffer在棧中,該內(nèi)存在堆中char *s = “hactrox”。// 指針s存放在棧中,字符串存放在文字常量區(qū)中char str[] = “hactrox”。// str和字符串存放在棧中static int a = 0。// a存放在全局靜態(tài)區(qū)的已初始化區(qū)}char *s = “hactrox”。// “hactrox”在文字常量區(qū),s指向這個(gè)區(qū)域中的“hactrox”,所以這可以理解為,首先在文字常量區(qū)創(chuàng)建了這個(gè)字符串,然后s指向這個(gè)字符串這樣兩個(gè)步驟。s本身作為一個(gè)局部變量存儲(chǔ)在棧中。// 下面的代碼是錯(cuò)誤的,指針還沒指向就直接賦值了?int *p = 5。// 下面的代碼才是正確的,首先要?jiǎng)?chuàng)建這個(gè)int型變量,然后p指向這個(gè)變量。new來的int變量在堆中。int *p = new int(5)。接下來我們看一看一個(gè)非常常見的問題:下述代碼有沒有什么問題?有問題的話問題在哪里?[cpp] view plaincopyprint?include using namespace std。char* f1
點(diǎn)擊復(fù)制文檔內(nèi)容
醫(yī)療健康相關(guān)推薦
文庫(kù)吧 www.dybbs8.com
備案圖片鄂ICP備17016276號(hào)-1