扣丁书屋

改变结构体成员的字节对齐

例子

#include <stdio.h>

typedef struct
{
        char a;
        int b;
} ST_A;

int main(void)
{
        printf("sizeof(ST_A)=%ld\n",sizeof(ST_A));
}

技巧

在上面的程序里,ST_A结构体的内存布局默认是这样的:

Offset 1byte 1byte 1byte 1byte
0 a 填充字节 填充字节 填充字节
4 b b b b

编译执行,结果如下:

root@ubuntu:~$ gcc -g -o a a.c
root@ubuntu:~$ ./a
sizeof(ST_A)=8

使用gcc的"-fpack-struct[=n]"选项(“n”需要为2的倍数)可以改变成员的地址对齐。例如指定“n=2”时,将标明结构体成员的最大对齐地址为2。这样ST_A结构体中的成员b的地址将不再按照4字节对齐,内存布局变为:

Offset 1byte 1byte 1byte 1byte
0 a 填充字节 b b
4 b b
编译执行,结果如下:
root@ubuntu:~$ gcc -g -fpack-struct=2 -o a a.c
root@ubuntu:~$ ./a
sizeof(ST_A)=6

当不指定“n”时,将没有填充字节,所有成员将一个挨着一个排在一起:

Offset 1byte 1byte 1byte 1byte
0 a b b b
4 b
编译执行,结果如下:
root@ubuntu:~$ gcc -g -fpack-struct -o a a.c
root@ubuntu:~$ ./a
sizeof(ST_A)=5

由于这个编译选项会导致ABI(Application Binary Interface)的改变,所以使用时一定要谨慎。 详情参见gcc手册

贡献者

nanxiao


GCC小技巧

目录