大多数计算机体系结构中,对内存操作时按整字存取才能达到最高效率,相当于是以空间换取时间,看似浪费了内存空间,但换来了存取效率,先来说说三个概念:系统对齐值,自身对齐值,有效对齐值,三个概念的单位均为字节,一开始概念不懂没关系,可以对照后面的程序和内存分布图来理解
1, 系统对齐值:
对于不同的操作系统,不同的开发环境,其默认的系统对齐值不同(通常是4或者8),在C语言里你也可以通过一个宏{ #pragma pack(n) }来自定义系统对齐值为n。
2,自身对齐值:
在结构体中,自身对齐值是指结构成员的类型所占字节数,例如: int a; 那么结构成员a的自身对齐值为4。
3,有效对齐值:
若系统对齐值>自身对齐值,则有效对齐值=自身对齐值。
若自身对齐值>系统对齐值,则有效对齐值=系统对齐值。
ok! 现在上图上代码
假设结构体首地址为0x00,在内存中,每一个成员要从离上一个成员最近,且能整除其有效对齐值的地址开始放置,放置大小为其类型所占字节数
结构体成员对齐
对于a,其有效对齐值为1,从0x00处放置1个字节
对于b,其有效对齐值为2,从0x02处放置4个字节
对于c,其有效对齐值为2,从0x06处放置2个字节
结构体整体对齐
经过上面结构体成员对齐后,内存中一共放置了8个字节,对于此时整个结构体来说,其自身对齐值=8,系统对齐值=2,那么其有效对齐值为2,有效对齐值能被自身对齐值整除,则不需要再补加内存字节填充,故最终结构体内存大小为8字节。
我们再来看看当系统对齐值为4的情况
假设结构体首地址为0x00,在内存中,每一个成员要从离上一个成员最近,且能整除其有效对齐值的地址开始放置,放置大小为其类型所占字节数
结构体成员对齐
对于a,其有效对齐值为1,从0x00处放置1个字节
对于b,其有效对齐值为4,从0x04处放置4个字节
对于c,其有效对齐值为2,从0x08处放置2个字节
结构体整体对齐
与图一不同,此时内存中一共放置了10个字节,对于此时整个结构体来说,其自身对齐值=10,系统对齐值=4,那么其有效对齐值为4,有效对齐值不能被自身对齐值整除,则需要再补加内存字节填充至刚好能整除(此处填充2字节),故最终结构体内存大小为12字节。
---------------------------------------增改------------------------------------------
描述:当自定义系统对齐值为8时,上述结构体大小仍为12,说明对于上述结构体,系统对齐值不全是由#pragma pack()决定,而是由#pragma pack()和结构体中最大字节类型共同决定,当结构体中最大字节类型 < #pragma pack(),则系统对齐值为结构体中最大字节类型。如上述结构体中,最大字节类型为int大小为4,#pragma pack()大小为8,则系统对齐值仍然为4。