内存对齐:
计算机把各种类型数据按照一定的规则在空间上排列,通过填充相应的字节把数据放在特定的地址上。
对齐原因:
(1)为了避免移植后计算机读取数据出错(各个硬件平台对存储空间的处理上有很大的不同,某些硬件平台只能在某些地址处去某些特定类型的数据,否则会出错)。
(2)为了提高计算机取数的效率(比如有些平台每次读都是从偶地址开始,如果一个int型(32位系统)如果放在偶数地址开始的地方,那么一一个读周期就可以读出这32bit,而如果存放在奇数地址开始的地方,就需要2个读数周期,并对两次读出的结果的高低字节进行并凑才能得到该32bit数据。显然在读取效率上下降了很多)。
对齐规则:
(1)结构体变量的首地址能够被其最宽类型成员的大小整除;
(2)结构体成员的首地址是其大小的整倍数,若不是,编译器在该成员与前一个成员之间填充相应的字节;
(3)结构体的大小是其最大成员大小的整倍数,若不是,编译器在最后一个成员后填充相应的字节;
如图所示:
#include <stdio.h>
struct A
{
char a;//1+3
int b;//4
};//8
struct B
{
char a;//1+3
int b;//4
short c;//2+2
};//12
struct C
{
short a;//2
char b;//1+1
int c;//4
};//8
struct D
{
char a;//1+1
short b;//2
char c;//1+3
int d;//4
};//12
struct E
{
char a;//1
char x;//保留1
short b;//2
int c;//4
};//8
struct I
{
char b;//1+3
int c;//4
}d;//8
struct II
{
int a;
struct I
{
char b;//1+3
int c;//4
}d;//8
};//12
int main()
{
printf("sizeof(struct A): %d\n",sizeof(struct A));
printf("sizeof(struct B): %d\n",sizeof(struct B));
printf("sizeof(struct C): %d\n",sizeof(struct C));
printf("sizeof(struct D): %d\n",sizeof(struct D));
printf("sizeof(struct E): %d\n",sizeof(struct E));
printf("sizeof(struct I): %d\n",sizeof(struct I));
printf("sizeof(struct II): %d\n",sizeof(struct II));
return 0;
}