c语言结构体边界对齐
2011-08-03 13:28
197 查看
通常情况下, 在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的时候这条指令并没有起作用。
例如:
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的时候这条指令并没有起作用。
相关文章推荐
- C语言结构体在内存中的布局(直接对齐)
- C语言结构体的字节对齐
- c#编程指南(十二) 平台调用P-INVOKE完全掌握, 结构体边界对齐和内存布局
- c语言中结构体的对齐方式
- c语言中的边界对齐
- C语言结构体--对齐说明
- C语言内存中结构体对齐分析
- 关于C语言中的结构体对齐问题
- C语言结构体的字节对齐原则
- <C语言>结构体与联合体(共用体)的地址排布问题(内存字节对齐)
- c语言学习零碎整理(2):结构体对齐问题
- 解析C语言结构体对齐(内存对齐问题)
- 解析C语言结构体对齐(内存对齐问题)
- C语言中结构体字节对齐
- C语言 内存中结构体字节对齐
- C语言结构体对齐
- C语言结构体中内存对齐问题
- C语言 结构体的内存对齐问题与位域
- C语言中结构体中变量存储的对齐问题
- C语言结构体的字节对齐实例【C语言笔试题】