目录
字节对齐
什么是字节对齐
从内存访问的效率出发,CPU底层或者编译器一般会要求,所有的对象的地址按照某种方式来对齐。
一般来说,就是要求对象的地址是n的倍数。
对齐方式
n字节对齐
对象的地址是n的倍数(n一般为2的x次幂)
eq:
4字节对齐:所有对象的地址必须为4的倍数。
8字节对齐:所有对象的地址必须为8的倍数。
16字节对齐:
。。。
GCC代码中:
程序员可以指定对齐方式:
__attribute__((aligned(n))
自然对齐
编译器默认的一种对齐方式(32bits与64bits编译器会有不一样)。
32bits | 64bits | |
char | 1字节对齐 | 1字节对齐 |
short | 2字节对齐 | 2字节对齐 |
int | 4字节对齐 | 4字节对齐 |
long | 4字节对齐 | 8字节对齐 |
long long | 4字节对齐 | 8字节对齐 |
any pointer | 4字节对齐 | 8字节对齐 |
double | 8字节对齐 | 8字节对齐 |
对象的地址必须是对象长度的倍数,什么意思呢?
举个栗子:
sizeof(int) = 4;
int a;
&a :必须为4的倍数
if &a不是4的倍数,说明a不是自然对齐。
sizeof(short) = 2;
short a;
&a : 必须为2的倍数
if &a不是2的倍数,说明a不是自然对齐
sizeof(long) = 8;
long b;
&b:b的地址必须是8的倍数
sizeof(char) = 1;
char c;
&c:c的地址必须是1 的倍数
每个变量(包括结构体中的成员变量)都会有一个默认的对齐方式:--》自然对齐
那么结构体的对齐方式
(1)结构体变量按其最大的类型成员变量的对齐方式对齐
(2)结构体的大小必须为其对齐方式的整数倍(一般都为向上取整)
举个例子:
struct test
{
char a; //a的对齐方式:一字节对齐
int b; //b对齐的方式:四字节对齐
short c; //c对齐的方式:2字节对齐
};
struct test 按照b的对齐方式进行对齐:4字节对齐
struct test 变量 (整个结构体)大小必须是4的整数倍。
sizeof(struct test); ==> 12
再思考两个
struct finalPadShort
{
short x;
char n[3];
};
sizeof(struct finalPad); //6
struct MixedData
{
char data1;
short data2;
int data3;
char data4;
};
sizeof(struct finalPad); //12
最后一个为什么是12呢,我们来看图,以下就是它的存储形式
地址低位 | 地址高位 | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|
char | short | short | X | int | int | int | int | char | X | X | X |
如图,第一个成员变量是char,占1字节,第二个成员变量是short,占2字节,这两个成员变量加起来没有超过int的4字节,可以放在一个4字节中,所以一共是3个4字节,
sizeof(struct finalPad) == 12。