指向变量的指针
您将addr
转换为指向int的指针,将其解引用并将其放入read_value
。
如果addr
真的是int
,我认为这是未定义的行为。
(int *) (addr)
将数值addr
转换为int *
指针。除非特别注意,否则此操作是不安全的,因为addr
的任意值可能违反int
的对齐要求。一般来说,如果addr
的值不是int
大小的倍数,则可能导致读取错位,最终可能会导致产生SIGBUS
信号。
星号最终获取位于该地址的int
值(称为解除引用)并将其保存到read_value
。如果地址没有被充分对齐,就会发生错位读取。如果地址碰巧受到限制或保护,解引用也可能导致分段错误。
我真的宣布addr
是uintptr_t
型的,而不是int
,因为这给投地int *
之间更安全。 uintptr_t
应该对应于指针的大小和表示,而int
类型在语义上与指针无关。
只是在这里添加,这种做法被称为“类型双关”。如前所述,这可能是危险的。如果不能确定对齐方式,可以使用'memcpy()'来读取“int”值。 – FatalError 2012-02-01 13:35:10
采取下面的例子:
int read_value = 0;
int address = 0x1234;
read_value = *(int *) address;
这相当于:
read_value = *(int *) 0x1234;
此在read_value
对象在地址0x1234
并存储读取int
。首先将int
值0x1234
转换为指向int
的指针,然后解引用指针以访问指向的值int
。
请注意,转换(int *) 0x1234
是实现定义的。
(C99,6.3.2.3p5)“的整数可以被转换为任何指针类型。除先前指定,其结果是实现定义的,可能无法正确对齐,可能没有指向的一个实体引用的类型,并可能是陷阱表示。“
而且,如果指针是无效指针或者它没有正确的对齐方式,则指针的取消引用是未定义的行为。任何使用无效指针都是未定义的行为。无效指针是一个不为空的指针,但不指向适当的对象或函数。
只有当强制转换导致无法表示的值时,才会出现未定义的行为。 (见C11 6.3.2.3)。 – Lundin 2012-02-01 15:20:31