2013-10-06 42 views
0

鑄造雙指針字符指針有什麼不妥?以下代碼的目標是以三種不同的方式更改1元素。鑄造/取消引用雙數組字符指針

double vec1[100]; 
double *vp = vec1; 
char  *yp = (char*) vp; 
vp++; 
vec1[1] = 19.0; 
*vp = 12.0; 
*((double*) (yp + (1*sizeof (vec1[0])))) = 34.0; 
+1

運行它時發生了什麼? –

+1

這段代碼與double vec1 [100]有什麼不同? vec1 [1] = 34.0;'? – Dan

+0

OP說目標是以多種方式操縱相同的元素 –

回答

0

這種類型的演員屬於「如果你知道自己在做什麼,但是如果你不知道如何做到危險」。

例如,在這種情況下,您已經知道「yp」的指針值(它指向double),因此在技術上可以安全地將其值增加double的大小並將其重新轉換回double*

一個反例:假設你沒有知道char*來自哪裏...說,它是作爲一個函數參數給你的。現在,你的演員陣容將是一個大問題:由於char*在技術上是1字節對齊的,而double通常是8字節對齊的,所以你不能確定你是否得到了8字節對齊的地址。如果它對齊,你的算術將產生一個有效的double*;如果不是這樣,它會在解除引用時崩潰。

這只是演員如何出錯的一個例子。你在做什麼(乍看之下)看起來會起作用,但總的來說,當你投擲東西時你必須注意。

+0

請注意,對齊不是使雙重有效的唯一的事情。許多位模式並不代表有效的雙精度...並且這也可能會根據您的FPU設置產生中斷。 –

+0

這是真的,但在這種情況下,他明確地通過每個指針分配有效的浮點數。 –

0

對於較新的INTEL處理器,您可以運行的主要問題是對齊。說你寫這樣的事:

*((double*) (yp + 4)) = 34.0; 

那麼你很可能有一個運行時錯誤,因爲雙應在8個字節對齊。處理器如68k或MIPS也是如此。

這類似於具有結構並在該結構上進行投射。你不可能破壞事物。

在大多數情況下,如果您可以避免這種情況,您的代碼會更強大。就我個人而言,在閱讀文件時我甚至不使用這種類型的演員。相反,我從文件中獲取數據並根據需要將其放入結構中。說我在一個緩衝區中讀取4個字節轉換爲整數,我會寫這樣的事:

unsigned char buf[4]; 
... 
fread(buf, 1, 4, f); 
my_struct.integer = buf[0] | (buf[1] << 8) | (buf[2] << 16) | (buf[3] << 24); 

現在我沒有做一個醜陋的演員和我可以控制文件中的整數的字節序什麼您正在運行的處理器的末端。

+0

這不符合OP的代碼--OP使用的是單個元素的'sizeof',所以沒有可以想象的對齊問題。 –

+0

爲什麼你需要使用'char *'指針,如果你手邊有'vec1'數組?我覺得奇怪的是,他使用'sizeof(vec1 [0])'而不是'sizeof(double)',但沒有發現它與我的答案有關。 –

+0

那麼,這個代碼的*目的*當然是籠罩在神祕之中的。我只是指出,如OP所寫,這是安全的。建議使用'sizeof(vec1 [0])',因爲這意味着你不重複數據類型,因此一旦你改變了聲明類型並且忘記改變類型其他使用地點。 –