C语言 -- 内存对齐

内存对齐

主要内容:

  1. 结构体内存对齐规则

  2. 内存对齐规则的探讨

  3. 为什么需要内存对齐

1. 结构体内存对齐规则

2. 内存对齐规则的探讨

2.1 用例代码

struct s1{
    char a;
    int b;
    double c;
};
void test(){
    s1 a;
    printf("struct sizeof : %d
", sizeof(a));
};

  测试结果:

    

  根据内存对齐规则对结果进行分析

    变量a是char类型,且为首成员变量,对齐到结构体内存地址的首地址处

    变量b是int类型,根据第二个规则,可得 对齐数 = (4 < 8) = 4,所以对齐到结构体内存地址为4的地址处

    变量c是double类型,同上,可得 对齐数 = (8 = 8) = 8,所以对齐到结构体内存地址为8的地址处

    从图中可以清晰看出,结构体每个变量的内存使用情况。现在结构体已经占用了16个字节,那么总结构体的大小为最大对齐数的整数倍,最大对齐数为8(c是double类型,对齐数为8),16刚好是8的整数倍,即结构体大小为16

2.2 尝试变换一下结构体成员位置

struct s2{
    double a;
    char b;
    int c;
};
void test(){
    s2 b;
    printf("struct sizeof : %d
", sizeof(b));
}

  测试结果:

    

  发现和上面测试结果一样,但看下内存占用情况,内存使用情况发生了改变

 

 2.3 再次变换一下结构体成员

struct s3{
    double a;
    int b;
    char c;
};
void test(){
    s3 c;
    printf("struct sizeof : %d
", sizeof(c));
}

  测试结果:

    

   发现测试结果和上面还是一样,再来看看内存使用情况

  

  此时,结构体成员占用的内存空间为13个字节,但根据内存对齐规则:结构体总的大小为最大对齐数的整数倍

  当前最大对齐数为8,13不是8的整数倍,所以输出结果为16

2.4 如果结构体嵌套使用呢?

struct s3{
    double a;
    int b;
    char c;
}
struct s4{
    char c1;
    s3 a;
}

  测试结果:

    

  根据内存对其规则:如果嵌套结构体,嵌套的结构体对齐到自己的最大对齐数的整数倍处,结构体的整体大小就是所有最大对齐数(包括嵌套结构体的对齐数)的整数倍

  分析结构体成员的内存占用情况

  

   此时,结构体成员总共占用了21个字节,根据内存对齐规则可知,结构体的大小为24

2.5 对s4中成员和嵌套的结构体进行换位

struct s3{
    double a;
    int b;
    char c;
}
struct s4{
    s3 a;
    char c1;
}

  测试结果:

    

   分析内存占用情况:

   总计占用13个字节,最大对齐数为8,所以结构体总的大小为16

3. 为什么需要内存对齐

  1. 平台原因(移植原因):

    不是所有的硬件平台都能访问任意地址的任意数据的;某些平台只能在某些地址处取某些特定类型的数据

  2. 性能原因:

    数据结构尤其是栈应该尽可能在自然边界上对齐。原因在于,为了访问未对齐的内存,处理器需要做两次访问内存;而对齐的内存访问仅需要一次访问。

  3. 缺点:存在效率问题,这是一种以空间换时间的做法,但这种做法是值得的

原文地址:https://www.cnblogs.com/bj3251101/p/14426808.html