内存对齐机制

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/happy_teemo/article/details/52180000

内存对齐机制(Memory Alignment):提高CPU访问内存数据的效率。

先看数组,由于数组的类型都一样,所以数组的大小=类型大小*成员个数。无缝隙存储。
但是结构体里面放的类型很多时候都不一样,那么就会有问题。
环境:假设是32位系统,则默认按4字节对齐。即4个一组,比如int型变量,则必须从0,4,8,12…这样的位置起头放(刚好被4整除)。如果是short,则是0,2,4,8…(刚好被2整除)。char就无所谓了,哪里都可以(都可以被1整除)。

32系统:计算机硬件+操作系统+编译器都是32位。

结论1:分配的首地址可以被该变量大小整除。如果默认是4字节对齐,那double这样超过4字节的,还是按4字节算。

//8=1+1+ 空两格 +4  
struct Demo1
{     
    char a;
    char b;
    int c;
};
//看起来是1+1+4 = 6;

但是如果是:

struct Demo2
{   
    int c;  //换了位置
    char a;
    char b; 
};
//看起来6,4是先放好了,再放两个1。但是还是8。

结论2:总大小必须为结构体中类型宽度最大的数据成员的宽度的整数倍。一样,如果默认是4字节对齐,那double这样超过4字节的,还是按4字节算。
也就是算出来是6,但是你最大的int是4,那么就要补成8。也就是后面空着的两位也算你的。

//12 = 1 + 空3个 + 4 + 1 + 空3个
struct Demo3
{
    char a;
    int i;
    char c;
};
//很浪费,所以尽量把类型一样的放在一起。

如果结构体A包含结构体B的东西:

struct Demo1
{     
    char a;
    char b;
    int c;
};//8
struct Demo5
{
    char c;
    struct Demo1 s;
};//4+8 = 12

此时结构体1的类型大于4,按4算(还是因为默认4字节对齐),然后char c就按4对齐。
如果:

struct Demo1
{     
    char a;
};//1
struct Demo5
{
    char c;
    struct Demo1 s;
};//1+1 =2

此时char c就按1对齐。

结论3:结构体A中有结构体B的成员,A的成员按结构体B中类型宽度最大的数据成员对齐。对齐规则参考结论1、2

以上都是按4字节对齐,4称为对齐模数,可以改:

#pragma pack(n) //按n字节对齐
#pragma pack () //解除对齐

如果按1字节对齐,那么就直接无脑加就好了。
其他的情况就依次按着结论把4依次改成n就好了。

展开阅读全文

没有更多推荐了,返回首页