我们应该只对数组使用指针算术运算,因为数组肯定分配在连续的内存块上,指针算术运算可以得到有效的偏移量。不过,不应该将它们用在结构体内,因为结构体的字段可能分配在不连续的内存区域。
下面这个结构体说明了这一点。为name
字段分配10字节,之后是一个整数。然而,整数是对齐到4字节边界的,所以两个字段之间会有空隙。这类空隙在6.1节的“结构体的内存如何分配”中解释过了。
下面的代码试图用指针来访问结构体的age
字段:
指针包含地址110,这是两个字段之间的2字节的地址,解引指针会把地址110处的4字节当做整数,如下图所示。
警告 误用对齐的指针可能会导致程序非正常终止或是取到错误数据。此外,如果编译器需要生成额外的机器码来弥补不恰当的对齐,那么指针访问也可能变慢。
即使结构体内的内存是连续的,用指针算术运算来访问结构体的字段也不是好做法。下面的结构体定义了由三个整数组成的Item
,通常会将三个整数字段分配在连续的内存位置,不过也不一定:
下面的代码片段声明了一个部件,然后用指针算术运算访问每个字段:
通常,输出就是我们所期望的那样,但也有例外。更好的办法是把每个字段赋给pi
:
更好的办法是根本不用指针,如下所示: