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

浅析C语言中的字节对齐

2016-04-25 21:25 246 查看
对于不同系统对字节对齐的要求略微有所差异,但是无论哪一个系统都是出于提高CPU和存储器之间的传输效率而采用了字节对齐。我们首先基于IA32体系架构来讨论字节对齐。

在32位Linux下,分2种对齐:以2字节对齐和以4字节对齐。对齐方式主要看所存储的数据类型的大小。2字节的数据类型以2字节地址对齐,大于或者等于4字节的数据类型以4字节对齐,假如数据大小为一个字节,则不用对齐存放。例子:

Struct P1{int i;char c;int j;char d;short s;char t};

对于上述结构体,有如下地址布局。结构体的起始地址假定为0,方块上边的数字为方块的起始地址(最后一个数字20例外,主要是为了显示整个struct的大小)



其中上图各部分含义如下:




这是一个比较有代表性的例子,根据之前的分析,有以下结论:

一、int类型的数据大小为4字节,所以4字节对齐,所以看到结构体中j成员并没有放在偏移地址为5处(int类型需要4字节对齐),而是放在偏移地址为8处,中间为空洞(浪费掉)。

二、char类型的数据大小为1字节,不用对齐,所以看到结构体成员中,char类型的成员是紧跟在上一个成员的后面存放。

三、short类型的数据大小为2字节,采用2字节对齐,所以我们可以看到S的起始地址并不是13,而是14。

四、最后考虑整个Struct,对于每一个大于1个字节的数据类型都需要对齐,那么一个Struct数据类型的对齐方式是什么呢?打个比方,类似在Struct P1 st[2]这样的定义中,st[1]的起始地址是什么呢?其实,Struct数据类型的对齐限制等同于它成员中对齐要求最严的那一个限制,本例中就是等同于int的4字节对齐。所以如上图,我在最后标记出偏移地址为20就是为了说吧假如有第二个Struct P1类型的变量起始地址就是20而不是17.(4字节对齐要求),所以sizeof(Struct P1)为20。

现在大家明白了吧,而对于字节对齐要求更加严格的x86-64,它对齐要求比IA32的要求严格,表现在8字节的数据类型如long、double数据类型需要8字节对齐,对于long double数据类型需要16字节对齐。但对于2字节和4字节的对齐要求一样。

有兴趣的朋友可以写出在x86-64架构下

Struct P1{int I;char c;long j;char d;};

Struct P2{strcut P1 a[2];struct P1 *p};

这两个结构体中各成员的偏移地址和结构体大小。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: