应用场景:计算一个结构体的大小
请看如下代码:
计算结构体A的大小,按照我们以往的理解,a1,c1为int类型,b1为char类型,则其大小应该为 4byte*2+1byte=9byte ,但是我们可以看到实际上编译器计算的大小为12byte。
这是为什么呢?这就引出了今天要和大家分享的内容–结构体大小的计算-结构体对齐。
首先向大家介绍结构体的对齐规则:
1.第一个成员在与结构体变量偏移量为0的地址处,也就是说第一个成员的位置就是结构体变量的开始地址。
2.其余的成员变量都要对齐到对齐数的整数倍地址处。
在此给出对齐数的概念:
是编译器默认的一个对齐数与该成员大小的较小值。
以VS编译器为例,其默认对齐数为8
3.结构体总的大小为所有成员最大对齐数的整数倍。
举例向大家说明,以前面的struct A为例,编译器为VS,则默认对齐数为8
首先首个成员a1在结构体地址偏移量为0地址处,大小为4byte
成员b1在结构体地址偏移量为4地址处,判断是否为对齐数的整数倍。
成员c1在结构体地址偏移量为5地址处,其对齐数为4,偏移地址不为对齐数整数倍,继续向后偏移,直至偏移量为8位置处,向后4byte。
全部成员分析完毕,再看整个结构体的大小,大小为12byte,所有成员最大对齐数为4,结构体的大小是成员最大对齐数的整数倍,分析完毕,否则继续向后偏移,直至满足条件为止。
再来看一道题目:
如下的结构体:
struct A{
long aa;
short bb;
int cc;
int *dd;
};
请问在64位编译器下用sizeof(struct A)计算出的大小是多少?( )
图解:
在vs当服务器托管网中验证一下:
结果正确!
在这个题目中需要特别注意的是指针类型的成员变量,在32位编译器中,任意类型的指针变量都是4byte,而在64位编译器中,任意类型的指针变量均为8byte。这一点在计算结构体大小时需要特别注意一下。
知道如何计算结构体大小之后,那么为什么会有这种对齐的机制呢?
1.平台原因(移植原因): 不是所有的硬件平台都能访问任意地址上的任意数据的;某些硬件平台只能在某些地址处取某些特定类型的数据,否则抛出硬件异常。
2. 性能原服务器托管网因: 数据结构(尤其是栈)应该尽可能地在自然边界上对齐。 原因在于,为了访问未对齐的内存,处理器需要作两次内存访问;而对齐的内存访问仅需要一次访问。
总体来说:
结构体的内存对齐是拿空间来换取时间的做法。
感兴趣的话还可以下来查阅更多的相关资料。
可以使用#pragma 预处理指令,改变默认对齐数。
e.g:#pragma pack(8)//设置默认对齐数为8
#pragma pack()//还原为默认对齐数
以上就是本次分享的全部内容,有错误欢迎指正!希望对大家有所帮助^-^
服务器托管,北京服务器托管,服务器租用 http://www.fwqtg.net
机房租用,北京机房租用,IDC机房托管, http://www.fwqtg.net