printf问题 近日在工作中遇到一个奇怪问题,A程序发送一个结构给B程序,在B程序接收后,B程序按照A程序的结构进行解析,但始终不对。看过结构定义后,虽然知道有可能会出现字节对齐问题,一直怀疑是他们消息传输构造不对。经过GDB确认A程序发出的结构是正确的,在B程序接收处也同样没问题。当调试到转化处时才发现确实是字节对齐导致的。下面举例说明(32bit Linux Gcc)。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 #include <stdio.h> typedef struct { unsigned int a; short int b; long long int c; unsigned int d; }type1; int main (int argc,char *argv[]) { type1 A={1 ,2 ,0x1234567890123456L L,0x87654321 },B,*C; B=A; C=&A; printf ("B={0x%x,0x%x,0x%x,0x%x}\n" ,B.a,B.b,B.c,B.d); printf ("C={0x%x,0x%x,0x%x,0x%x}\n" ,C->a,C->b,C->c,C->d); return 0 ; } 输出: B={0x1 ,0x2 ,0x3 ,0x0 } C={0x1 ,0x2 ,0x3 ,0x0 }
从上面这个示例可以看出,输出的结果与我们预期的不一样。这是因为在32位系统下,数据存储将按结构体成员的最大字节数对齐,并且最大字节数为4。因此如type1结构体将按4字节对齐,变量A/B/C字节流为:
01 00 00 00 02 00 00 00 03 00 00 00 00 00 00 00 04 00 00 00
GDB显示如下,其中b显示0x02 0x00 0x04 0x08,是由于没有清掉之前的缓存。
1 2 3 4 5 6 (gdb) x/30x C 0xbffff328: 0x01 0x00 0x00 0x00 0x02 0x00 0x04 0x08 0xbffff330: 0x03 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0xbffff338: 0x04 0x00 0x00 0x00 0x28 0xf3 0xff 0xbf 0xbffff340: 0xd0 0x84 0x04 0x08 0xf4 0xff (gdb)