addr
是函数的参数,read_value
是函数的局部变量。两者都是int类型。
然后是什么:
read_value = (* (int *) (addr))
意思?
答案 0 :(得分:4)
(int *) (addr)
将addr
的数值转换为int *
指针。除非特别小心,否则此操作不安全,因为任意值addr
可能违反int
的对齐要求。通常,如果addr
的值不是int
大小的倍数,则可能导致读取错位,最终会导致SIGBUS
信号。
星号最终取出位于该地址的int
值(称为取消引用)并将其保存到read_value
。正是在这一点上,如果地址没有充分对齐,可能会发生未对齐的读取。如果地址恰好被限制或受到保护,则取消引用也可能导致分段错误。
我实际上会将addr
声明为uintptr_t
类型,而不是int
,因为这样可以提高演员与int *
之间的安全性。 uintptr_t
应该对应于指针的大小和表示,而int
类型在语义上与指针无关。
答案 1 :(得分:1)
您将addr
转换为指向int的指针,取消引用它,并将其放入read_value
。
如果addr
确实是int
,我认为这是未定义的行为。
答案 2 :(得分:1)
采用以下示例:
int read_value = 0;
int address = 0x1234;
read_value = *(int *) address;
这相当于:
read_value = *(int *) 0x1234;
这会在地址int
处读取0x1234
并将其存储在read_value
对象中。首先将int
值0x1234
转换为指向int
的指针,然后取消引用指针以访问指向的int
值。
请注意,转化(int *) 0x1234
是实施定义。
(C99,6.3.2.3p5)“整数可以转换为任何指针类型。除了先前指定的,结果是实现定义的,可能没有正确对齐,可能不指向引用类型的实体,可能是陷阱表示。“
如果指针是无效指针或者没有正确的对齐方式,则指针的取消引用是未定义的行为。使用无效指针是未定义的行为。无效指针是一个非空指针,但不指向正确的对象或函数。