问题:
问题1:
struct X{char a; //1float b; //4int c; //4double d; //8unsigned e; //4};
由于存储变量时地址对齐的要求,所以这个结构体大小应该是32。
解答:
struct X {char a; // 1 byteschar padding1[3]; // 3 bytesfloat b; // 4 bytes--int c; // 4 byteschar padding2[4]; // 4 bytes--double d; // 8 bytes--unsigned e; // 4 byteschar padding3[4]; // 4 bytes--};
注意:
- 对于所有基本类型,align(T)==sizeof(T)
- 那 align(X) 是多少呢?当然就是所有成员里面 align 最大的那个,是 align(d)==8
padding1的存在是因为,offset(b)必须能够被align(b)整除,所以塞三个char。
b的偏移字节是它自身字节的整数倍,因此要添加三个字节的偏移
padding2的存在是因为,offset(d)必须能够被align(d)整除,所以塞4个char。
原因同上
padding3的存在是因为,因此sizeof(X)必须能够被align(X)整除,就有了。
整个结构体的大小必须能被其中最大align的数整除。
备注:
C++内置的offsetof函数,能自动返回结构对象中,某变量距离结构体对象首地址的偏移值:
offsetof(s, m);
参数:
- 第一个参数是一个结构体
- 第二个参数是这个结构体中变量的名字
这个宏会返回那个变量距结构体头部的字节偏移量(Byte Offset)。
问题2: 如果我多定义一个任意型的指针
struct X{char a;float b;int c;double d;unsigned e;int *f;};
结果这样结构体大小就直接变成40了。
如果指针大小是地址总线大小的话,2个指针就是8字节,加上原来的32字节也刚好等于40字节,并且也满足存储变量时地址对齐的要求。但是为什么刚才加一个指针不变,两个就变了。
解答:
struct X {char a; // 1 byteschar padding1[3]; // 3 bytesfloat b; // 4 bytes--int c; // 4 byteschar padding2[4]; // 4 bytes--double d; // 8 bytes--unsigned e; // 4 bytesint *f; // 4 bytes--};
解答: 再加一个指针以后
struct X {char a; // 1 byteschar padding1[3]; // 3 bytesfloat b; // 4 bytes--int c; // 4 byteschar padding2[4]; // 4 bytes--double d; // 8 bytes--unsigned e; // 4 bytesint *f; // 4 bytes--double *g; // 4 byteschar padding3[4]; // 4 bytes--};
