2012-02-01 160 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)“的整数可以被转换为任何指针类型。除先前指定,其结果是实现定义的,可能无法正确对齐,可能没有指向的一个实体引用的类型,并可能是陷阱表示。“

而且,如果指针是无效指针或者它没有正确的对齐方式,则指针的取消引用是未定义的行为。任何使用无效指针都是未定义的行为。无效指针是一个不为空的指针,但不指向适当的对象或函数。