#include <stdio.h>struct stu1{ char a; int b; short c;}stu1;struct stu2{ short c; char a; int b;}stu2;struct stu3{ char a; short c; int b;}stu3;struct stu4{ char a; int b; short c; double d; char e;}stu4;int main(int argc, char *argv[]){ printf("stu1.a:%p stu1.b:%p stu1.c:%p sizeof(stu1):%d/n", &stu1.a, &stu1.b, &(stu1.c), sizeof(stu1)); printf("stu2.c:%p stu2.a:%p stu2.b:%p sizeof(stu2):%d/n", &stu2.c, &stu2.a, &(stu2.b), sizeof(stu2)); printf("stu3.a:%p stu3.c:%p stu3.b:%p sizeof(stu3):%d/n", &stu3.a, &stu3.c, &(stu3.b), sizeof(stu3)); printf("stu4.a:%p stu4.b:%p stu4.c:%p stu4.d:%p stu4.e:%p sizeof(stu4):%d/n", &stu4.a, &stu4.b, &stu4.c, &stu4.d, &stu4.e, sizeof(stu4)); return 0;}运行结果如下分析stu1:从stu1结构体可以看到,a是一个char型,为一个字节,接下来为int b,为整形,四个字节,这时候离结构体首地址(即a的地址)的偏移为4(规则b),所以a必须再填充三个字节(从打印的地址也可以看出,即0x6010a9、0x6010aa、0x6010ab),然后short c为2个字节,而且距离首地址偏移为6能整除2(short) 所以加起来为4+4+2 = 10字节。这时候肯定很多人疑问了,这不10字节么?怎么打印的是12呢?那么现在我们的规则c起作用了(即结构体本身的对齐),在64位系统下,#pragma pack(8) 为8,stu1结构体中最大的类型为int,4个字节,所以我们需要在short c后面填充2个字节(从打印地址可以看出,c的首地址为0x6010b0、那么填充的地址应该为0x6010b2、0x6010b3),所以总共的字节数为4+4+2+2 = 12 (字节)。中间两个就不分析了,按着规则去一步一步匹配就行,而且地址我都打印出来了应该好判断,接着分析下stu4。分析stu4:从stu4结构体可以看到(和结构体stu1相似,我特意添加了一个double和char来区分下以及更加好理解规则c),char a,int b,short c,我就不再具体分析,可以看下分析stu1,算到这里我们知道是4+4+2 = 10 字节,接下来是double d,为8字节,到这里我们可以知道a+b+c+d = 4+4+2+8 = 18(这时候注意了,根据规则b,我们知道18是不能整除8的,所以必须填充4字节,为18+6 = 24),所以这时候我们不妨看看打印的地址是否和我们想的一样(short c的首地址为0x601088,占2字节,0x601088~0x601089,从图中我们可以看到d的首地址为0x601090,所以就证实了我们说的需要填充6个字节,即0x60108a~0x60108f),最后加上char e ,1个字节,为25字节,这时候我想很多人应该知道了,根据我们的规则c,在64位系统下,#pragma pack(8) 为8,stu4结构体中最大的类型为double,8个字节,所以我们需要在char e后面在填充7个字节,即0x601099~0x6010af,所以总共的字节数为1+3(填充)+4+2+6(填充)+8+1+7(填充) = 32(字节)。由于上周看到网上很多对内存对齐都讲的很模糊,所以决定自己玩一遍,毕竟身为程序猿各种玩就是@_@,周末总结下希望能帮助到别人!!!该睡觉了,还要上班明天......
新闻热点
疑难解答