您的位置:首页 > 编程语言 > C语言/C++

C语言中的字节对齐问题

2010-04-03 16:18 239 查看
struct 是一种复合数据类型,其构成元素既可以是基本数据类型(如 int 、 long 、 float 等)的变量,也可以是一些复合数据类型(如 array 、 struct 、 union 等)的数据单元。对于结构体,编译器会自动进行成员变量的对齐,以提高运算效率。缺省情况下,编译器为结构体的每个成员按其自然对界( natural alignment )条件分配空间。各个成员按照它们被声明的顺序在内存中顺序存储,第一个成员的地址和整个结构的地址相同。
 
一、自然对界 (natural alignment) 即默认对齐方式,是指按结构体的成员中基本类型size 最大的成员对齐。(注意:记住是基本类型 !)
例如:有如下结构体
struct PRG
  5 {
  6     int c;
  7     union
  8     {
  9         char st[6];
 10         int i;
 11         long int j;
 12     }test;
 13     char b;
 14 };
按照自然对界方式,应以成员 j 类型(long int)大小对齐,即8字节;则sizeof(struct PRG)为 24;在内存中结构图如下:
|————————|————————|————————|
 
|int c  |  填充  |  union test    |b|   填充       |
 
以下再给几个例子,让读者好好体会上面的文字的意思,特别是红色标记的字眼。
struct testa
 17 {
 18     char a;
 19     char b;
 20     char c;
 21 }ta;                                        sizeof(ta) 为 3
 
struct testb
 17 {
 18     char a;
 19     char b[3];
 20     char c;
 21 }tb;                                        sizeof(tb) 为 5
 
struct testc
 17 {
 18     char a;
 19     short b;
 20     char c;
 21 }tc;                                        sizeof(tc) 为 6
 
struct testd
 17 {
 18     char a;
 19     char c;
 20     short b;
 21 }td;                                        sizeof(tc) 为 4 (因为a与c合在一起刚好对齐)
 
struct teste
 17 {
 18     char a;
 19     int b;
 20     char c;
 21 }te;                                        sizeof(tc) 为 12
 
struct testc
 17 {
 18     char a;
 19     char c;
 20     int b;
 21 }tc;                                        sizeof(tc) 为 8
 
二、改变对齐的方式。
在缺省情况下,C编译器为每一个变量或是数据单元按其自然对界条件分配空间。
 
一般地,可以通过下面的方法来改变缺省的对界条件:  
     ·使用伪指令#pragma pack(n),C编译器将按照n个字节对齐。  
       ·使用伪指令#pragma pack(),取消自定义字节对齐方式。
注意:如果 #pragma pack (n) 中指定的 n 大于结构体中最大(指基本类型)成员的 size ,则其不起作用,结构体仍然按照 size 最大的成员进行对齐。
    
另外,还有如下的一种方式:  
       ·__attribute__((aligned(n))),让所作用的结构成员对齐在n字节自然边界上。如果结构中有成员的长度大于n,则按照最大成员的长度来对齐。  
       ·__attribute__((packed)),取消结构在编译过程中的优化对齐,按照实际占用字节数进行对齐.
 
注意:上述的n必须为2的某次方!
 
例:
#pragma pack(4)
 struct PRG
  5 {
  6     int c;
  7     union
  8     {
  9         char st[6];
 10         int i;
 11         long int j;
 12     }tes
a929
t;
 13     char b;
 14 };
#pragma pack()                  则sizeof(struct PRG)为 16
 
#pragma pack(1)
 struct PRG
  5 {
  6     int c;
  7     union
  8     {
  9         char st[6];
 10         int i;
 11         long int j;
 12     }test;
 13     char b;
 14 };
#pragma pack()                  则sizeof(struct PRG)为 13
 
#pragma pack(16)
 struct PRG
  5 {
  6     int c;
  7     union
  8     {
  9         char st[6];
 10         int i;
 11         long int j;
 12     }test;
 13     char b;
 14 };
#pragma pack()                  则sizeof(struct PRG)仍为 24
 
struct PRG
  5 {
  6     int c;
  7     union
  8     {
  9         char st[6];
 10         int i;
 11         long int j;
 12     }test;
 13     char b;
 14 }__attribute__((aligned(4)));      则sizeof(struct PRG)仍为 24
 
struct PRG
  5 {
  6     int c;
  7     union
  8     {
  9         char st[6];
 10         int i;
 11         long int j;
 12     }test;
 13     char b;
 14 }__attribute__((aligned(16)));      则sizeof(struct PRG)为 32
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息