问题:
问题1:
struct X
{
char a; //1
float b; //4
int c; //4
double d; //8
unsigned e; //4
};
由于存储变量时地址对齐的要求,所以这个结构体大小应该是32。
解答:
struct X {
char a; // 1 bytes
char padding1[3]; // 3 bytes
float b; // 4 bytes--
int c; // 4 bytes
char padding2[4]; // 4 bytes--
double d; // 8 bytes--
unsigned e; // 4 bytes
char 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 bytes
char padding1[3]; // 3 bytes
float b; // 4 bytes--
int c; // 4 bytes
char padding2[4]; // 4 bytes--
double d; // 8 bytes--
unsigned e; // 4 bytes
int *f; // 4 bytes--
};
解答: 再加一个指针以后
struct X {
char a; // 1 bytes
char padding1[3]; // 3 bytes
float b; // 4 bytes--
int c; // 4 bytes
char padding2[4]; // 4 bytes--
double d; // 8 bytes--
unsigned e; // 4 bytes
int *f; // 4 bytes--
double *g; // 4 bytes
char padding3[4]; // 4 bytes--
};