2012-02-01 235 views
2

addr是該函數的參數,而read_value是該函數的局部變量。都是int類型的。指向變量的指針

那麼,什麼是:

read_value = (* (int *) (addr)) 

是什麼意思?

回答

1

您將addr轉換爲指向int的指針,將其解引用並將其放入read_value

如果addr真的是int,我認爲這是未定義的行爲。

+0

只有當強制轉換導致無法表示的值時,纔會出現未定義的行爲。 (見C11 6.3.2.3)。 – Lundin 2012-02-01 15:20:31

4

(int *) (addr)將數值addr轉換爲int *指針。除非特別注意,否則此操作是不安全的,因爲addr的任意值可能違反int的對齊要求。一般來說,如果addr的值不是int大小的倍數,則可能導致讀取錯位,最終可能會導致產生SIGBUS信號。

星號最終獲取位於該地址的int值(稱爲解除引用)並將其保存到read_value。如果地址沒有被充分對齊,就會發生錯位讀取。如果地址碰巧受到限制或保護,解引用也可能導致分段錯誤。

我真的宣佈addruintptr_t型的,而不是int,因爲這給投地int *之間更安全。 uintptr_t應該對應於指針的大小和表示,而int類型在語義上與指針無關。

+1

只是在這裏添加,這種做法被稱爲「類型雙關」。如前所述,這可能是危險的。如果不能確定對齊方式,可以使用'memcpy()'來讀取「int」值。 – FatalError 2012-02-01 13:35:10

1

採取下面的例子:

int read_value = 0; 
int address = 0x1234; 

read_value = *(int *) address; 

這相當於:

read_value = *(int *) 0x1234; 

此在read_value對象在地址0x1234並存儲讀取int。首先將int0x1234轉換爲指向int的指針,然後解引用指針以訪問指向的值int

請注意,轉換(int *) 0x1234是實現定義的。

(C99,6.3.2.3p5)「的整數可以被轉換爲任何指針類型。除先前指定,其結果是實現定義的,可能無法正確對齊,可能沒有指向的一個實體引用的類型,並可能是陷阱表示。「

而且,如果指針是無效指針或者它沒有正確的對齊方式,則指針的取消引用是未定義的行爲。任何使用無效指針都是未定義的行爲。無效指針是一個不爲空的指針,但不指向適當的對象或函數。