Type: note
Intro
Local Variable 的 memory 位置 和 return value主要是要測試 class 在 function return 時 的問題
但用 int 比較方便解釋, 所以這邊用 int 作測 試
int get1(){ int rs = 1; printf("%d : %d\n", &rs, rs); return rs;} int* get2(){ int rs = 2; printf("%d : %d\n", &rs, rs); return &rs;} int& get3(){ int rs = 3; printf("%d : %d\n", &rs, rs); return rs;} int& get4(){ int *rs = new int(4); printf("%d : %d\n", rs, *rs); return *rs;}
Content
case 1
int _tmain() { printf("---case 1---\n"); int idx1 = get1(); // 1899836 : 1 printf("%d : %d\n\n", &idx1, idx1); // 1900144 : 1 //位置不一樣, 沒問題
case 2
printf("---case 2---\n"); int *idx2 = get2(); // 1899836 : 2 printf("%d : %d\n\n", idx2, *idx2); // 1899836 : 2 //傳pointer, 位置一樣, 沒問題?
*idx2 = 22; printf("%d : %d\n\n", idx2, *idx2); // 1899836 : 22 // 指定該位置 為 22, 沒問題?
int *idx2_2 = get2(); // 1899836 : 2 printf("%d : %d\n\n", idx2, *idx2); // 1899836 : 2 printf("%d : %d\n\n", idx2_2, *idx2_2); // 1899836 : 20518839這邊再 get 另一個 int *idx2_2
你的 compiler 很可能跟我一樣
在執行 get2() 時, 被分配的記憶體, 跟上次一樣
這時問題就出現了
1. 跟上次取得的idx2有衝突
2. Why?
關於(1.): 沒錯 起衝突了, 所以我們列印 idx2 卻發現原本修改成 22 的數值 變成 2 了
關於(2.): 之所以會有這狀況是因為 stack-allocated. 我們在呼叫 function 時, local variable 會被暫存到其它地方, 直到 該function執行結束, 準備返回到原本的function時, 才會被寫回來.
所以 在 get2() 裡, 被配置的位置, 即使被傳回來 也應該是不能用的
像是line3. 僅只是經過了一個 printf, 同一個位置的值卻被改掉了. 主要是因為, 那個位置 在離開 get2() 後 就不屬於你的了, 也就是本來就沒有配置給你
*idx2 = 23; printf("%d : %d\n\n", idx2_2, *idx2_2); // 1899836 : 23想當然爾~ 如果改了 idx2, 會連同 idx2_2 一起改掉(同一個位置)
P.S. 即使2次分配的記憶體不同, 那個位置也不是能傳回來用的
case 3
咱們換成 & 來試試
printf("---case 3---\n"); int idx3 = get3(); // 1899836 : 3 printf("%d : %d\n\n", &idx3, idx3); // 1899836 : 3 int& idx3_3 = get3(); // 1899836 : 3 printf("%d : %d\n\n", &idx3_3, idx3_3); // 1899836 : 3 printf("%d : %d\n\n", &idx3_3, idx3_3); // 1899836 : 20331817結果一樣, 在第二次 print idx3_3 時, 數值被改變了
case 4
使用 new 的方式, 是可以在離開 function (scope) 時, 保留該配置 (參閱 C++ new class or not
接著測試此方式
printf("---case 4---\n"); int idx4_bad = get4(); // 597336 : 4 printf("%d : %d\n\n", &idx4_bad, idx4_bad); //1900084 : 4 //delete &idx4_bad;//failed如果咱們 單純的宣告一個 int 去接收它, 那只是接收了它的值
沒辦法刪除它(原本new出來的
int& idx4 = get4(); // 618240 : 4 printf("%d : %d\n\n", &idx4, idx4); // 618240 : 4 delete &idx4;咱們要宣告 int& 去接收它, 這樣他們才會指向同一個物件, 也才可以刪除它
P.S. new 出來的記憶位址跟其它的不太一樣
Conclusion
local variable 的配置 只在該 scope 有效
注意 傳入 及 傳回 的類型
沒有留言:
張貼留言