Re: [問題] *ptrptr++ 與 (*ptrptr)++

看板C_and_CPP (C/C++)作者 ( )時間16年前 (2009/07/24 22:30), 編輯推噓3(300)
留言3則, 3人參與, 最新討論串3/3 (看更多)
※ 引述《IDontBite (大便兔子)》之銘言: 先假設你外面大概是這樣送: void foo() { int *ptr; test(&ptr); } : void testing(int **ptr){ : cout<<*ptr<<endl; 上面這行印出 0x19, 這值蠻少見的所以我前面猜你是沒初始化 ptr 就直接送, 不過這對你的問題倒沒什麼影響。 : *ptr++; 這整道敘述同「ptr++;」, 事實上你傳進去的東西也不是什麼 2d array, 所以 ptr++ 跳上去已經不知道指向什麼東西了, 雖然講是這樣講其實學過 PL 或 compiler 的都知道, 這個位置一定落在 stack 裡當前 function 所屬的 activation record 上或隔壁。 : cout<<*ptr<<endl; 這邊印出 0x3e3970, 正常, 其實它會是什麼值都不意外。 : (*ptr)++; 這行是做 *ptr = *ptr + 1, 算是破壞你 stack 的第一個兇手, *ptr = ... 不管你右邊寫了什麼東西, 只要不是 *ptr = *ptr; 基本上就死了, 要是 *ptr 剛好紀錄你 function 的 return address, 你的 function 一 return 就會 return 到神奇的地方去, 至於有沒有這麼準就看你環境用的 calling convention 是怎樣。 : cout<<*ptr<<endl; 這裡印出 0x3e3974, 它也是無意義的值所以不必理會, 雖然講是講無意義的值其實可能有人猜得出它是什麼東西, 只要熟悉你執行平台跟編譯環境的 calling convention 就行。 : *ptr = *ptr + sizeof(int); 這一步是毀滅你 stack 的另一個兇手。 : cout<<*ptr<<endl; 這裡印出的 0x3e3984 已經無意義, 不過可以推出原值是 0x3e3984 - sizeof(int), 反正也是某個 activation record 裡某個欄位的值。 : return;} : 以上這段程式碼, 傳一個int*的位址進去之後得到以下結果 : 0x19 : 0x3e3970 : 0x3e3974 : 0x3e3984 : 從2到3行應該是*ptr前進一個int大小, 所以+4 : 3到4行是*ptr前進sizeof(int) = 4個int大小, 所以+16, 用16進制所以看起來像+10 : 但第1行到第2行到底發生了甚麼事 <囧> 這個bug搞了我一整天, 很想弄清楚 : 麻煩各位了<(_ _)> -- Ling-hua Tseng (uranus@tinlans.org) Department of Computer Science, National Tsing-Hua University Interesting: C++, Compiler, PL/PD, OS, VM, Large-scale software design Researching: Software pipelining for VLIW architectures Homepage: https://www.tinlans.org -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 118.160.117.31 ※ 編輯: tinlans 來自: 118.160.117.31 (07/24 22:51)

07/24 22:58, , 1F
推:)
07/24 22:58, 1F

07/24 23:49, , 2F
07/24 23:49, 2F

07/25 17:26, , 3F
@O@ 超詳細的! 謝謝!
07/25 17:26, 3F
文章代碼(AID): #1AQSM6ZN (C_and_CPP)
討論串 (同標題文章)
文章代碼(AID): #1AQSM6ZN (C_and_CPP)