这个问题在这里已经有一个答案:>
Is apparent NULL pointer dereference in C actually pointer arithmetic?5个
我在一本书中发现这个代码示例,但是我无法理解printf语句中的表达式.
并且该程序成功地编译输出为4.
好心提醒…
我在一本书中发现这个代码示例,但是我无法理解printf语句中的表达式.
并且该程序成功地编译输出为4.
好心提醒…
void main(){ unsigned char c; typedef struct name { long a; int b; long c; }r; r re = {3,4,5}; r *na=&re; printf("%d",*(int*)((char*)na + (unsigned int ) & (((struct name *)NULL)->b))); }
解决方法
让我们从最后一行开始:
printf("%d",*(int*)((char*)na + (unsigned int ) & (((struct name *)NULL)->b)));
让我们解释一下:
(unsigned int ) & (( (struct name *)NULL)->b )
实际上是铸造(((struct name *)NULL) – > b)转换成unsigned int.
&安培; (((struct name *)NULL) – > b)是地址(即给出指针):
(( (struct name *)NULL)->b )
这实际上是b(作为name.b)从NULL(0)的偏移量,它是4个字节(假设长度为4个字节)并转换为int的指针,给出2(假设int为2个字节).
如果不是NULL,那么它将是一个指向0xFFFF0000的指针,那么&(ptr-> b)将是0xFFFF0002.但是它更像&(0 – > b),所以它的0x00000002.
所以,(unsigned int)& (((struct name *)NULL) – > b)== 2(或者可能是1,或者可能是4,取决于机器).
其余的是简单的:*(int *)((char *)na 2将指向重新设置b,所以应该打印4(在代码中初始化了r re = {3,5} ).
P.S:即使(unsigned int)& (((struct name *)NULL) – > b)!= 2(也许是1,4或8) – 它仍然打印4,因为它然后使用相同的偏移来获取值.