为什么要对齐
- 32位架构的cpu,4个字节为一个读周期,设4字节变量在内存首地址为addr
- addr出现在4的整数倍地址处,方便一个读周期读取
- 若跨越2个周期拼凑一个4字节,效率低
对齐值
- 自身对齐值
- 整数类型自身的对齐值:内置类型自己的尺寸
- 结构体自身对齐值:数据成员最大的那个自身对齐值
- 指定对齐值:程序员指定的那个值,不同平台指定的方式:
// vs
#progma pack(8) // 指定为8字节,32位系统默认为4字节
此时再定义结构体,此结构体的对齐值就是8字节
#pragma pack() // 取消指定
// linux
typedef struct student{}__attribute__((packed)) student;
结构体对齐要求
- addr为结构体的对齐起始地址:
addr%有效对齐值==0
- 每个数据成员x都要对齐addr:
addr%x有效值==0
- 结构体自身也要对齐addr:
addr%st有交值==0
- 若无法整除,则addr递增,直接可以整除所有成员及结构体变量本身为止
typedef struct student // C与C++结构体,C++中的类,都可以部分初始化
{ // id:指定4 自身4 有效4 地址:00-03
int id;
// name:指定4 自身7 有效4 地址:04-11,其中10-11补足1字节
char name[7];
// sa:指定4 自身2 有效2 地址:12-15,其中14-15补足2字节
short sa;
struct
{
// month:指定4 自身4 有效4 地址:16-19
int month;
// ch1:指定4 自身1 有效1 地址:20-23,其中21-23补足3字节
char ch1;
// L:指定4 自身8 有效4 地址:24-32
long long L;
}date; //结构体本身 指定4 自身16 有效4
}student; // sizeof(student)==32
// 当系统默认的为4,当指定为8时,其结果一样,因为8是读周期4字节的倍数
// 当指定对齐值为2字节时,为28字节,主要少了sa补足的2字节,ch1只需补1字节,省了2字节
// 当指定对齐值为1字节时,为26字节,全不需要补足。