[問題] 指標轉型問題

作者: cityhigh (city)   2015-01-17 14:53:20
開發平台(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):
作者: PkmX (阿貓)   2015-01-17 15:46:00
pointer轉成int在轉回來本來就是不合法的事情...你如果要存可以指向任何type的指標請用void*舉例來說在x86_64底下sizeof(int) == 4 ; sizeof(int*) == 8至於為什麼str1宣告成global就可以 應該是因為他擺在bss剛好被map在32-bit可以表示的範圍內 如果是擺在stack上面通常是擺在high address 所以一轉換就爛了
作者: cityhigh (city)   2015-01-17 16:33:00
還是不太懂,一轉換就爛掉指的是什麼?對test()和test2()來看,傳入的address印出來也是一樣的
作者: wenyonba (射後不理很XX啊!!!!)   2015-01-17 16:50:00
他應該是說,你把8bit轉成4bit,那是要拿低位還是高位?如果Compiler拿的狀況不如你的預期,不就掛了我這樣說會不會有點病...
作者: azureblaze (AzureBlaze)   2015-01-17 17:42:00
保證能轉的只有intptr_t和uintptr_t
作者: PkmX (阿貓)   2015-01-17 20:54:00
https://gist.github.com/PkmX/a0073d4d7904137d9638可以看到stack上面的位置轉成int再轉回void*值根本就錯了而global變數因為位置數字夠小 所以轉換"剛好"沒問題不過重點就是別依賴這種"剛好"的行為 挑正確的type去裝才對而且其實把void*轉成int編譯的時候就會產生warning了=.=
作者: bibo9901 (function(){})()   2015-01-17 21:02:00
http://tinyurl.com/3d487sk板友的大作, 裡面講得很清楚
作者: Killercat (殺人貓™)   2015-01-18 00:10:00
別想些有的沒的 乖乖用void*中轉吧....c就算了 c++其實根本沒必要做這種沒意義的亂轉就是
作者: LPH66 (-6.2598534e+18f)   2015-01-18 02:39:00
真想轉成整數的話轉成 intptr_t 就什麼事都沒有
作者: carylorrk (carylorrk)   2015-01-18 13:00:00
又不是做 compiler 研究,標準說有問題就不要用,不要去研究為什麼結果剛好正確或是為什麼回事這樣。這是等你熟悉了語言和平臺想自己研究再說
作者: TobyH4cker (Toby (我要當好人))   2015-01-18 13:34:00
原因PkmX說了,int 還是4 Bytes應該建議一下版主現在發問還要提供平台為x86還是x86_64
作者: cityhigh (city)   2015-01-19 09:16:00
感謝各位大大

Links booklink

Contact Us: admin [ a t ] ucptt.com