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