[問題] 指標轉型問題

看板C_and_CPP作者 (city)時間9年前 (2015/01/17 14:53), 9年前編輯推噓2(2027)
留言29則, 9人參與, 最新討論串1/1
開發平台(Platform): (Ex: VC++, GCC, Linux, ...) GCC 額外使用到的函數庫(Library Used): (Ex: OpenGL, ...) 問題(Question): 在ST_TEST str1為local變數時, 將指標轉型成int,再將int轉回成指標後, 會發生Segmentation fault。不轉型的話就不會有問題。 test()和test2()說明轉型和不轉型的差型。 但如果將ST_TEST str1; 定為成global變數,test2()的轉型也還可以使用。 int main() { ST_TEST str1; test(&str1); test2((int)(&str1)); } void test(ST_TEST *const str_point) { ST_TEST str2; memcpy((ST_TEST *)&str2, (ST_TEST *)str_point, sizeof(ST_TEST)); } void test2(int str_int) { ST_TEST str3; memcpy((ST_TEST *)&str3, (ST_TEST *)str_int, sizeof(ST_TEST)); } 餵入的資料(Input): 預期的正確結果(Expected Output): 錯誤結果(Wrong Output): 程式碼(Code):(請善用置底文網頁, 記得排版) http://pastebin.com/cMiJiCsf 補充說明(Supplement): -- ※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 180.43.50.107 ※ 文章網址: https://www.ptt.cc/bbs/C_and_CPP/M.1421477604.A.ED3.html ※ 編輯: cityhigh (180.43.50.107), 01/17/2015 14:54:22 ※ 編輯: cityhigh (180.43.50.107), 01/17/2015 14:56:09

01/17 15:46, , 1F
pointer轉成int在轉回來本來就是不合法的事情...
01/17 15:46, 1F

01/17 15:47, , 2F
你如果要存可以指向任何type的指標請用void*
01/17 15:47, 2F

01/17 15:49, , 3F
舉例來說在x86_64底下sizeof(int) == 4 ; sizeof(int*) == 8
01/17 15:49, 3F

01/17 16:19, , 4F
至於為什麼str1宣告成global就可以 應該是因為他擺在bss剛好
01/17 16:19, 4F

01/17 16:20, , 5F
被map在32-bit可以表示的範圍內 如果是擺在stack上面通常是
01/17 16:20, 5F

01/17 16:21, , 6F
擺在high address 所以一轉換就爛了
01/17 16:21, 6F

01/17 16:33, , 7F
還是不太懂,一轉換就爛掉指的是什麼?
01/17 16:33, 7F

01/17 16:34, , 8F
對test()和test2()來看,傳入的address印出來也是一樣的
01/17 16:34, 8F
※ 編輯: cityhigh (180.43.50.107), 01/17/2015 16:43:30 ※ 編輯: cityhigh (180.43.50.107), 01/17/2015 16:43:51

01/17 16:50, , 9F
他應該是說,你把8bit轉成4bit,那是要拿低位還是高位?
01/17 16:50, 9F

01/17 16:51, , 10F
如果Compiler拿的狀況不如你的預期,不就掛了
01/17 16:51, 10F

01/17 16:51, , 11F
我這樣說會不會有點病...
01/17 16:51, 11F

01/17 17:42, , 12F
保證能轉的只有intptr_t和uintptr_t
01/17 17:42, 12F


01/17 20:55, , 14F
可以看到stack上面的位置轉成int再轉回void*值根本就錯了
01/17 20:55, 14F

01/17 20:56, , 15F
而global變數因為位置數字夠小 所以轉換"剛好"沒問題
01/17 20:56, 15F

01/17 20:56, , 16F
不過重點就是別依賴這種"剛好"的行為 挑正確的type去裝才對
01/17 20:56, 16F

01/17 20:58, , 17F
而且其實把void*轉成int編譯的時候就會產生warning了=.=
01/17 20:58, 17F

01/17 21:02, , 18F

01/17 21:03, , 19F
板友的大作, 裡面講得很清楚
01/17 21:03, 19F

01/18 00:10, , 20F
別想些有的沒的 乖乖用void*中轉吧....
01/18 00:10, 20F

01/18 00:11, , 21F
c就算了 c++其實根本沒必要做這種沒意義的亂轉就是
01/18 00:11, 21F

01/18 02:39, , 22F
真想轉成整數的話轉成 intptr_t 就什麼事都沒有
01/18 02:39, 22F

01/18 13:00, , 23F
又不是做 compiler 研究,標準說有問題就不要用,不要
01/18 13:00, 23F

01/18 13:01, , 24F
去研究為什麼結果剛好正確或是為什麼回事這樣。
01/18 13:01, 24F

01/18 13:01, , 25F
這是等你熟悉了語言和平臺想自己研究再說
01/18 13:01, 25F

01/18 13:34, , 26F
原因PkmX說了,int 還是4 Bytes
01/18 13:34, 26F

01/18 13:36, , 27F
應該建議一下版主現在發問還要提供平台為x86還是x86_6
01/18 13:36, 27F

01/18 13:36, , 28F
4
01/18 13:36, 28F

01/19 09:16, , 29F
感謝各位大大
01/19 09:16, 29F
文章代碼(AID): #1KkWRaxJ (C_and_CPP)