最近找工作,被笔试给卡死了,很多基础都忘了,今天花了半天缕了下结构体内存对齐,整理下自己的心得,有哪里写错请指出。
我们直接例子说明:
typedef struct TEST{
int a;
char b[2];
double c;
short d;
double e;
} test;
sizeof(test) = ?;
看了网上好多文章,都是三类规则,个人还是不能完全理解(只理解结构体最后大小要是成员中最大成员大小的整数倍,我比较笨吧),说说内存方面的个人理解。
看下图
a放在结构体首地址(占四个字节),这个还是比较好理解
|—|—|—|—|—|—|—|—|—|—|—|—|—|—|—|—|—|—|—|—|—|—|—|—|—|—|—|—|—|—|—|—|
此时内存大小 = 4;
b 放在哪呢,b是char类型,大小是sizeof(char) = 1,此时内存位置为4是1的倍数,可以连续接下去。
|—|—|—|—|—|—|—|—|—|—|—|—|—|—|—|—|—|—|—|—|—|—|—|—|—|—|—|—|—|—|—|—|
此时内存大小 = 4+2;
c是double类型,大小sizeof(doubel) = 8, 那么c放哪呢,c只能放在内存位置为(0,8,16,24....),此时内存为6 != 8的倍数,
所以内存不能连续接下去了,那么>6又是8的最小倍数的不就是8咯,那就从内存地址8开始咯
|—|—|—|—|—|—|—|—|—|—|—|—|—|—|—|—|—|—|—|—|—|—|—|—|—|—|—|—|—|—|—|—|
此时内存大小 = 4+2+2(没人用)+8;
d是short类型,大小sizeof(short) = 2, d只能放在内存位置为(0,2,4,6...),此时内存为16 = 2的倍数,可连续接下去
|—|—|—|—|—|—|—|—|—|—|—|—|—|—|—|—|—|—|—|—|—|—|—|—|—|—|—|—|—|—|—|—|
此时内存大小= 4+2+2(没人用)+8+2
e是double类型,大小sizeof(doubel) = 8, 那么e放哪呢,和c一样,只能放在内存位置为(0,8,16,24....),此时内存为18 !=8的倍数,
所以内存也不能连续下去,那么>18又是8的最小倍数是多少呢,不就是3*8=24吗,那就从24开始嘛
|—|—|—|—|—|—|—|—|—|—|—|—|—|—|—|—|—|—|—|—|—|—|—|—|—|—|—|—|—|—|—|—|
得出的结构体大小= 4+2+2(没人用)+8+2+6(没人用)+8 = 32, 是结构体中最大成员类型double大小=sizeof(double)的整数倍?刚好32 = 8*4,
如果不足怎么办(假设最后结构体大小=30怎么办呢,那就在最后30的内存位置再加上2的内存,补足8的倍数咯),那就在最后的内存补上不足的内存呗。
最后sizeof(test) = = 32。
个人的理解是:每个结构体成员的存址位置都是该成员类型大小(sizeof(char), sizeof(int), sizeof(double)等)的整数倍内存位置开始存储。