資源描述:
《淺談c++中的內(nèi)存管理》由會員上傳分享,免費(fèi)在線閱讀,更多相關(guān)內(nèi)容在行業(yè)資料-天天文庫。
1、淺談C++中的內(nèi)存管理2003-08-0414:43作者:曹翼飛出處:放飛技術(shù)網(wǎng)責(zé)任編輯:方舟 摘要: 大家都知道變量的生存周期這個概念,可是有的時候變量生存周期已經(jīng)結(jié)束,但是所分配的那塊內(nèi)存空間還是存在的。文章舉了四個不同的例子,來說明這其中的原因?! ∏把裕骸 ∏耙欢螘r間在一個好友的的博客論壇上看到他學(xué)習(xí)C++時遇到的一小點(diǎn)問題,是關(guān)于C++中最基本的內(nèi)存分配方面的。其實(shí)對于內(nèi)存這東西,除了知道我自己用的是256M的內(nèi)存以外,我也不太清楚他到底里面是怎么工作的。看了大師們的講解,我深有體會,把這些講解整理出來,為所有C++的newbie們共勉! 正文: 事情是因?yàn)檫@
2、樣一小段程序而來的。intmain(){ inti=10; int*j=&i; if(!0) { intl=20; int*k=&l; j=k; k=0; } cout<<*j; return0;} 不用編譯器,大家想想執(zhí)行過之后應(yīng)該打印什么結(jié)果?我想大家的第一反應(yīng)應(yīng)該是打印出一個不確定的數(shù)。理由是在if語句里,我們定義了k這個變量,在if執(zhí)行結(jié)束之后,這個變量k所占據(jù)的內(nèi)存是被系統(tǒng)收回的,于是也就造成了變量j所指的結(jié)果非常不確定。當(dāng)然,如果編譯并且執(zhí)行過后,我們發(fā)現(xiàn)事情并不是像我們想象的那樣,程序最終的打印結(jié)果是20,并不是我們期待的一
3、個不確定的數(shù)。下面就讓我們分析一下原因吧! 我們用debug的方式來一步一步的分析,在watch的窗口下輸入里面所有的變量。inti=10; //iis10and&iis0x0012ff7cint*j=&i; //*jis10and&jis0x0012ff7c //顯然可以看出此時兩個變量指的是同一地址if(!0){ intl=20;//lis20and&lis0x0012ff74 /*地址0x0012ff7c—0x0012ff75被占據(jù)。要說明的是, 這個數(shù)值很有可能因?yàn)殡娔X硬件的不同而不同。*/ int*k=&l;//*kis20and&kis0x001
4、2ff74 //變量k與l指向同一地址。 j=k; //jis0x0012ff74and*jis20 /*指針間的賦值,這個語句的意思是把k指向的地址負(fù)值給j?! 〈藭r這兩個變量指向的是同一個地址,都是0x0012ff74,而那 塊地址存放的是20,所以也就有*j是20的原因。*/}cout<<*j; //*jis20andjis0x0012ff74/*此時同時可以看到k的地址是0x00000000,說明k這個變量已經(jīng)被自動銷毀,所以地址指零。但是j所指的并不是k,而是k所指的那段地址0x0012ff74,而由于此時j的生存周期還沒有結(jié)束(j是在if意外定義的),所以j
5、指向的這塊地址并沒有被收回,也就保存下來20這個數(shù)了。*/ 至此,我們分析完了程序的全過程的內(nèi)存分配情況,最終結(jié)果是這樣的。(圖1) 我們同時也可以在Memory里面看看這個地址的具體內(nèi)容。我們可以看到是14,這是十六進(jìn)制的數(shù),化成十進(jìn)制,正好是20。(圖2) 現(xiàn)在大家應(yīng)該對上面那個程序的執(zhí)行過程有一個大概地了解了吧!不過這個還不是我們想要得到的結(jié)果,我們需要的是打印一個不確定的結(jié)果。有了以上的分析,我們開始新的程序,讓他打印出我們想要的東西。 對于上面的程序,我們需要改動的是令變量j指向一個地址被釋放的位置。于是就有了下面的程序。int*foo(){ intl=20
6、; return&l;}intmain(){ inti=10; int*j=&i; j=foo(); cout<<*j; return0;} 編譯器很“聰明”,編譯后會給出一個警告。原話是“returningaddressoflocalvariableortemporary”,指向的是上面程序的第四行,也就是return&l;這條語句。那句英文的意思也不用我再多解釋了,相信大家都能看得明白?! ?zhí)行的結(jié)果,在debug下,是20;在release下,結(jié)果是4198795。顯然那部分內(nèi)存被釋放掉了。這是因?yàn)樵赿ebug的程序里面,執(zhí)行完函數(shù)foo,并沒有立即釋放掉l
7、的那個地址(目前我不清楚這句話說得是否精確)。在這個程序的release版本中,顯然程序釋放了那部分的地址,所以指向了一個不確定的數(shù)。這里還要說一件事情,就是在第一個程序當(dāng)中,無論是debug版本還是release版本。執(zhí)行完那個if語句以后,系統(tǒng)都是不會真正的把l清除掉,l只是k的一個別名。上面的程序是這樣寫的,用了*j=&i這樣一句負(fù)值語句,而別名在MSDN中的解釋與引用是相同的,所以也可以這樣理解,inti=10;int&j=i;與上面的相同。不要去想上面這些程序了,大家再看看下面這個