腾讯笔试之结构体地址对齐
昨天参加了腾讯的线上笔试,有一道题目是关于C语言结构体地址对齐的,当时不会算,后来看到了知乎的这个问题http://www.zhihu.com/question/28958350#answer-12470052 总结一下。
首先是结构体中变量x的地址偏移量offset(x)必须能被align(x)整除,而且应该是总线宽度的倍数。对于32位系统来说,总线宽度为32位=4byte,对于64位系统来说,总线宽度为64位=8byte。而对于一个结构体X来说,align(X)=align(x),而align(X)的值即为结构体中所有成员里面的最大align()值,成员地址对齐即为与这个值对齐。
下面看这个例子:
struct X
{
char a;
float b;
int c;
double d;
unsigned e;
};
在结构体X中,double类型变量的align()值最大,因此align(X)=align(d),从上往下分析,a为char类型,占1个字节,因此至少填充三个字节;b为float类型,占四个字节,不需要填充;c为int类型,占4个字节,但因为d是double类型,为了保证offset(b)能够被align(b)整除,因此填充4个字节;d为double类型,因此占8个字节;e为unsigned类型,在32位系统中占用4个字节,64位系统中占用8个字节。因为sizeof(X)必须能够被align(X)整除,因此填充够8个字节。
贴轮子哥的回答如下:
struct X { char a; // 1 bytes char padding1[3]; // 3 bytes float b; // 4 bytes int c; // 4 bytes char padding2[4]; // 4 bytes double d; // 8 bytes unsigned e; // 4 bytes char padding3[4]; // 4 bytes };
padding1的存在是因为,offset(b)必须能够被align(b)整除,所以塞三个char
padding2的存在是因为,offset(d)必须能够被align(d)整除,所以塞4个char
对于所有基本类型,align(T)==sizeof(T),所以有了上面两条,
那align(X)是多少呢?当然就是所有成员里面align最大的那个,是align(d)==8
好了,因此sizeof(X)必须能够被align(X)整除,就有了padding3。