内存对齐
内存对齐
(一)概念
所谓内存对齐是指,cpu在读取内存地址的时候,按照一定的偏移量去读取。
(二)好处
以空间换时间,提高读取效率。
理由如下:若#pragma pack(4)
不对齐:
若指定cpu读取单位为4字节,而int a = 0;保存在1,2,3,4中,
则cpu先读取0,1,2,3后,去掉高位0,然后再读取4,5,6,7,去掉低位5,6,7,如此,才能完整读取出a的值。

对齐:

则cpu只需访问内存一次,就可读取到a的值。
(三)对齐规则
- 结构体第一个成员的偏移量为0,以后每个成员相对于结构体首地址的offset都是该成员大小与有效对齐值中较小那个的整数倍,如有需要编译器会在成员填充字节。
- 结构体的总大小为有效对齐值的整数倍,如有需要编译器会在最末一个成员之后填充字节。
Tips:
有效对齐值:是给定值#pragma pack(n)中和结构体中最长数据类型较小的那个。
(四)例子
#pragma pack(4)//32bits
struct A{
int i;
char c1;
char c2;
};
sizeof(A) === 8
struct B{
char c1;
int i;
char c2;
};
sizeof(B) === 12
struct C{
char c1;
char c2;
int i;
};
sizeof(C) === 8
分析:
该情况下,有效对齐值 = 4字节
i: 本身大小 = 有效对齐值 即,0x0,0x1,0x2,0x3
c1: 本身大小= 1 < 有效对齐值,即0x4也为1的整数倍,则占0x4
c2: 本身大小 = 1 < 有效对齐值,即0x5也为1的整数被,则占0x5
按照规则2,则编译器补齐2bits到0x7
结构体总大小 = 4+1+1+2=8

情况二:
若设定编译器的对齐方式为2字节
#pragma pack(2)
分析:
i: 本身大小 > 有效对齐值 即,0x0,0x1,0x2,0x3(0x0为2的整数倍)
c1: 本身大小= 1 < 有效对齐值,即0x4也为1的整数倍,则占0x4
c2: 本身大小 = 1 < 有效对齐值,即0x5也为1的整数被,则占0x5
结构体总的大小 = 6字节
因此,结构体数据成员的声明顺序是影响其占用的内存大小的。
浙公网安备 33010602011771号