1.内存对齐
1.1 什么是内存对齐
操作系统一般是按照一定长度对内存数据进行处理的,我们常见的32位和64位操作系统,他们默认处理内存的长度分别是4bytes和8bytes。
因此我们在写程序的时候,也需要考虑这一点,如果不考虑内存对齐,考虑如下一个结构体:
struct A {
short s;
int i;
} a;
假设当前的设备是32位操作系统,内存地址从0x0000开始。
不做内存对齐这个结构体a存储的地址为:
0x0000-0x0001: s
0x0002-0x0005: i
当我们要取用i这个参数的值时,操作系统只能先把第一块内存(0x0000-0x0003)取出来,然后把第二块内存(0x0004-0x0007)取出来,然后分别取高2bytes和低2bytes组合在一起才能得到i的值。
如果我们做4bytes对其,这个结构体a存储的地址为:
0x0000-0x0003: s
0x0004-0x0007: i
这样我们无论时取s,还是取i,都可以只做一次读取就可以获得,并且不需要做位操作组合这些内存块,极大地提高了程序处理的速度。
1.2 怎么做内存对齐?
内存对齐其实我们的编译器会帮忙做,比如前面的结构体a,如果你是32bytes的编译器,那么就会自动做4bytes对齐,不需要我们人为指定。
当然我们也可以用预处理语句pragma pack自己指定内存对齐的字节数,比如:
#pragma pack(2)
struct A {
bool b;
short s;
int i;
};
#pragma pack() // 恢复默认的字节对齐
这样对齐的结果就是,b(0x0000-0x0001)、s(0x0002-0x0003)、i(0x0004-0x0007),这里虽然bool类型只占一个byte,但是因为做了对齐,还是会放到两个bytes的内存里。
1.3 示例
示例代码:
struct A {
bool b;
int i;
short s;
};
struct B {
int i;
short s;
bool b;
};
#pragma pack(2)
struct C {
bool b;
int i;
short s;
};
#pragma pack()
int main()
{
std::cout << "size A=" << sizeof(A) << ",size B=" << sizeof(B) << ",size C=" << sizeof(C) << "\n";
return 0;
}
运行结果:
size A=12,size B=8,size C=8
标签:struct,int,0x0000,学习,bool,内存,对齐
From: https://www.cnblogs.com/echizen/p/17258948.html