c语言结构体边界对齐

来源:互联网 发布:如何当一个网络写手 编辑:程序博客网 时间:2024/05/16 14:33

通常情况下, 在x86体系结构的系统上定义一个结构体的时候, 编译器会自动将结构体中的成员按4字节对齐的方式存储。

例如:

struct st_tst {

int a;

char b;

int c;

char d;

};

当我们计算sizeof(struct st_tst)的时候, 得到的值是16。也就是说即使成员b只需要占用一个字节的内存,但是为了让c能存储在四字节对齐的内存空间上,编译器将b后面的三个字节给跳过了,同理d也一样,保证后面的数据能在四字节上对齐。


进行字节对齐的原因是因为处理器在存取内存的时候并不是一个字节一个字节操作的, 通常他会一次存取多个字节, 比如四个。所以将数据以四字节对齐方式存储能够提高数据存取效率(其实具体的存储和对齐方式没那么简单,不说了)。但是, 有时候这种默认的优化并不是我们想要的。比如在设计网络程序的时候,一般情况下我们会定义一个结构体来表示应用程协议的协议头,如果通信双方的程序是在不同体系结构的计算机编译出来的(这很有可能),那么默认的对齐方式是有可能是不同的,这样解析出来的协议头必然就是错的。 另外即使很幸运的对齐方式一样,在协议头里面插入了几个无关的字节那也是很不优雅的何况还占用带宽。


还好,这种对齐方式我们是可以控制的,一般地,可以通过下面的方法来改变缺省的对齐方式:

  · 使用伪指令#pragma pack (n),编译器将按照n个字节对齐;

  · 使用伪指令#pragma pack (),取消自定义字节对齐方式。 

注意:如果#pragma pack (n)中指定的n大于结构体中最大成员的size,则其不起作用,结构体仍然按照size最大的成员进行对界。

例如还是刚才上面那个例子,当伪指令pragma中的n分别是1,2,4,8的时候sizeof(struct st_tst)的结果分别是10,12,16,16。当n等于8的时候这条指令并没有起作用。

原创粉丝点击