结构体内存对齐有两大规则
规则1:结构中的元素都是按照定义一个一个按顺序放到内存中去的,但不是紧密存储的。从结构体的起始位置开始,在每个元素放到内存的时候他们各自认为前面的元素都是按照自己的大小来划分的,因此位置一定是从自己大小的整数倍上开始的。(以结构体的起始位置从0开始)
规则2:在规则1的基础上,结构体的总大小是其中所有元素中宽度最大的整数倍,不够要补齐。
tpedef struct Struct
{
char a;
int b;
double c;
}s1;
再放a将放在地址0,放b时他认为前面的都是按照他的大小来存放的,a只占了一个字节,所以要补齐到4个字节,所以b放在3~7,放c时因为前面刚好8个字节,所以c放在8~15,所以这个结构体的大小为16;
typedef struct Struct
{
double a;
char c;
int b;
char d;
}s2;
根据规则1求出其大小为8+4+4+1 = 17,但是不是最大宽度8的倍数所以要补齐,sizeof(s2)的大小为24;
typedef struct Struct
{
double a;
char c;
int b;
char d;
int e;
}s3;
在s2的基础上再加个int型,其sizeof(s3)大小依然是8+4+4+4+4=24。
如果其基本变量中存在指针变量时,不论什么类型指针,指正本身只占4个字节。
struct s1
{
char a;
int b;
double c;
};
struct s2
{
char a;
s1 b;
};
经测试,可知sizeof(s1)为16,sizeof(s2)为24。即计算s2的存储长度时,在存放第二个元素b时的初始位置是在double型的长度8的整数倍处,而非16的整数倍处,即系统为b所分配的存储空间是第8~23个字节。
如果将s2的两个元素char型的a和s1型的b调换定义顺序,则系统为b分配的存储位置是第0~15个字节,为a分配的是第16个字节,加起来一共17个字节,不是最长基本类型double所占宽度8的整数倍,因此要补齐到8的整数倍,即24。测试后可得sizeof(s2)的值为24。