返回顶部

【学习总结】内存对齐学习汇总

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
posted @ 2023-03-26 16:49  藤原豆腐店の張さん  阅读(10)  评论(0编辑  收藏  举报