編譯器很“聰明”,編譯后會(huì)給出一個(gè)警告。原話是“returning address of local variable or temporary”,指向的是上面程序的第四行,也就是return &l;這條語(yǔ)句。那句英文的意思也不用我再多解釋了,相信大家都能看得明白。
執(zhí)行的結(jié)果,在debug下,是20;在release下,結(jié)果是4198795。顯然那部分內(nèi)存被釋放掉了。這是因?yàn)樵赿ebug的程序里面,執(zhí)行完函數(shù)foo,并沒(méi)有立即釋放掉l的那個(gè)地址(目前我不清楚這句話說(shuō)得是否精確)。在這個(gè)程序的release版本中,顯然程序釋放了那部分的地址,所以指向了一個(gè)不確定的數(shù)。
這里還要說(shuō)一件事情,就是在第一個(gè)程序當(dāng)中,無(wú)論是debug版本還是release版本。執(zhí)行完那個(gè)if語(yǔ)句以后,系統(tǒng)都是不會(huì)真正的把l清除掉,l只是k的一個(gè)別名。上面的程序是這樣寫的,用了*j=&i這樣一句負(fù)值語(yǔ)句,而別名在MSDN中的解釋與引用是相同的,所以也可以這樣理解,int i=10; int &j=i;與上面的相同。不要去想上面這些程序了,大家再看看下面這個(gè)。
void f1( int *& j) { int l=20; int *k=&l; j=k; k=0; }
void any_function_use_local_variables() { int a,b,c; a=b=c=100; }
int main() { int i=10; int *j=&i; f1(j); cout<<*j; any_function_use_local_variables(); cout<<*j; return 0; } |
請(qǐng)大家自己編譯、執(zhí)行,看看結(jié)果是什么,然后結(jié)合上面的兩個(gè)例子,想想是為什么。下面再給大家一個(gè)小例子,可能會(huì)有助于理解內(nèi)存的概念。
程序的過(guò)程是試圖去增加i,使之超過(guò)最大的整數(shù)。有一種情況是這個(gè)值被“卷回來(lái)”變成一個(gè)負(fù)數(shù),在我的機(jī)器上程序的打印結(jié)果是-2147483648,這個(gè)結(jié)果可能因?yàn)橛布牟煌煌?BR>
int main() { int i=1; while(0<i) i++; cout<<i; return 0; } |
結(jié)束:
其實(shí)我對(duì)于內(nèi)存的理解也是極為有限的。討論這個(gè)問(wèn)題的原帖子在這里。里面回答問(wèn)題的全都是Microsoft MVP或者是準(zhǔn)MVP,我也是從那里學(xué)習(xí)過(guò)來(lái)的。希望大家能從我的這篇文章中受益。這樣,也就達(dá)到了我寫文章的目的。:P