Q我有一些代码试图解包外部结构,但它以“未对齐访问”的消息崩溃。这是什么意思?代码如下
struct mystruct { char c; long int i32; int i16; } s; char buf[7], *p; fread(buf, 7, 1, fp); p = buf; s.c = *p++; s.i32 = *(long int *)p; p += 4; s.i16 = *(int *)p;
A问题在于您对指针的使用过于随意。有些机器要求数据值必须存储在对齐的地址中。例如,两个字节的short ints 可能被限制在偶数地址,而四个字节的long ints 则被限制在四的倍数地址。(另请参阅问题 2.12。) 通过将一个char *(可以指向任何字节) 转换为一个int *或long int *,然后对其进行解引用,您可能会要求处理器从一个未对齐的地址获取多字节值,而处理器不愿意这样做。
解析外部结构体的更好方法是使用类似以下的 C 代码:
unsigned char *p = buf; s.c = *p++; s.i32 = (long)*p++ << 24; s.i32 |= (long)*p++ << 16; s.i32 |= (unsigned)(*p++ << 8); s.i32 |= *p++; s.i16 = *p++ << 8; s.i16 |= *p++;
这段代码还可以让您控制字节序。 (不过,此示例假设char是 8 位,并且从“外部结构体”中解析的long int和int分别是 32 位和 16 位。) 有关一些解释和注意事项,请参阅问题 12.42 (其中包含一些类似的代码)。
另请参阅问题 4.5。
参考文献:ISO Sec. 6.3.3.2, Sec. 6.3.4
H&S Sec. 6.1.3 pp. 164-5