prev up next   top/contents search

comp.lang.c FAQ 列表· 问题 16.7

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 intint分别是 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


prev up next   contents search
关于此 FAQ 列表   关于 Eskimo   搜索   反馈   版权

Eskimo North 托管