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

C/C++ struct 成员对齐

2016-05-22 17:58 381 查看
偶然发现一篇文章写的挺通俗易懂的,不是太理解的童鞋可以看看。。。

struct 成员对齐比较经常听到的是:



1.内存对齐:计算机系统对基本类型数据在内存中存放的位置有限制,它们会要求这些数据的首地址的值是某个数k(通常它为4或8)的倍数k则被称为该数据类型的对齐模数(alignment modulus)

2.不同编译器默认的最大对齐字节数是不一样的,比如vc==8,gcc==4,可以通过#progma pack (n)来修改,分析程序的时候要注意编译器的区别

3.一个结构体里面,按照alignment modulus最大的数据成员来进行对齐,超过编译器规定最大的对齐字节个数,按编译器最大对齐字节个来

4.double类型在vc里面alignment modulus == 8,而在gcc里面由于默认最大对齐个数是4,不设置的话,alignment modulus == 4

5.因为数组各元素之间不能有空隙,所以{int a;char b;}

这种情况,默认在VC里面也需要占8个字节.



比较有歧义和费解的是第三点,经常搞晕,

废话少说直接上例子环境VC,32系统中:

(引用Nicolase的专栏 http://blog.csdn.net/nicolase/article/details/6626898)

struct Example1
{
char c;
int i;
double d;
};

struct Example2
{
char c;
double d;
int i;
};


结果是:sizeof Example1 = 16; sizeof Example2 = 24

这两个例子中重点分析下;

Example1:

第一个成员c 直接从偏移0开始,char 占一个字节,是1的整数倍,所以分配一个字节;

第二个成员i从偏移1开始,int占4个字节(32位系统),但是偏移1不是4的倍数,所以需要在偏移1后填充3个字节,所以i实际是从偏移4开始,分配4个字节空间;

第三个成员d从偏移8开始,double占8个字节,此时偏移8 是d类型的大小的倍数(8是8的倍数,这个没有疑问吧。。)

最后一个要求!!!struct 的总长度必须是结构体成员中数据类型中最大长度的整数倍!!!,struct Example1 总大小是(4+4+8=16) ,其中成员最大的数据类型是8(double),是其整数倍,OK,分析完毕。

Example2:

第一个成员c 直接从偏移0开始,char 占一个字节,是1的整数倍,所以分配一个字节;

第二个成员d从偏移1开始,double占8个字节(32位系统),但是不是8的倍数,所以需要在偏移1后填充7个字节,所以d实际是从偏移8开始,分配8个字节空间;

第三个成员i从偏移16开始,int占4个字节,此时偏移16 是d类型的大小的倍数,不用调整;

最后一个要求!!!struct 的总长度必须是结构体成员中数据类型中最大长度的整数倍!!!,struct Example2 总大小是(8+8+4=20) ,其中成员最大的数据类型是8(double),不构成整数倍,那就在后面填充到是为止。最后Example2的实际大小是(8+8+8=24),OK,分析完毕了。。

最后强调下:

1、逐个按顺序分配空间,偏移量必须是当前变量类型的整数倍,如果不是填空字节补充。

2、得到的最后长度,必须是struct 成员变量中字节最长类型的整数倍。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息