• 【C语言】-结构体内存对齐。附详细图解



    前言

    这篇文章笔者总结了结构体内存对齐的内容,这部分内容非常重要,并且易错点。


    1、结构体内存对齐的外在表现

    先看代码:

    struct S1
    {
     	char c1;
    	int i;
     	char c2;
    };
    printf("%d\n", sizeof(struct S1));
    //练习2
    struct S2
    {
     	char c1;
     	char c2;
     	int i;
    };
    printf("%d\n", sizeof(struct S2));
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    这两段代码的运行结果是什么?都是6?
    答案出乎意料:
    在这里插入图片描述
    分别是12、8
    为什么会是这样的结果?
    这就是笔者这篇博客要深入探讨的内容:结构体内存对齐

    2、结构体对齐的基本规则

    下面笔者给出原创超祥解图:
    在这里插入图片描述
    通过这张图,我们了解了结构体内存对齐的前三条规则,我们同理可以得到第二段代码的打印数为 8.与上述分析过程是一模一样的。
    但是内存对齐不止三条规则。第四条规则为:

    1. 如果嵌套了结构体的情况,嵌套的结构体对齐到自己的最大对齐数的整数倍处,结构体的整 体大小就是所有最大对齐数(含嵌套结构体的对齐数)的整数倍

    这里笔者就不给出第四条规则的详解了,相当于将嵌套的结构体当作一个变量,类似于上述变量开辟空间的过程。

    3、为什么要结构体内存对齐?

    这里笔者总结了两条原因:

    1. 平台原因(移植原因): 不是所有的硬件平台都能访问任意地址上的任意数据的;某些硬件平台只能在某些地址处取某些特 定类型的数据,否则抛出硬件异常。

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

    第一条原因笔者不做过多赘述,具体意思如文字所描述。对于第二条原因,笔者再次通过画图加深你对第二条原因的理解。
    在这里插入图片描述

    所以总体来说,我们可以概括为:结构体内存对齐是为了用空间换取性能

    4、一些关于内存对齐的小细节

    1.当我们在设计结构体时,我们要让占用空间小的成员尽量集中在一起。

    从而又能实现对齐又能不浪费空间。

    2.我们可以通过#pragma pack来实现默认对齐数的修改

    例如:

    #include 
    #pragma pack(8)//设置默认对齐数为8
    struct S1
    {
     char c1;
     int i;
     char c2;
    };
    #pragma pack()//取消设置的默认对齐数,还原为默认
    #pragma pack(1)//设置默认对齐数为1
    struct S2
    {
     char c1;
     int i;
     char c2;
    };
    #pragma pack()//取消设置的默认对齐数,还原为默认
    int main()
    {
        //输出的结果是什么?
        printf("%d\n", sizeof(struct S1));
        printf("%d\n", sizeof(struct S2));
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
  • 相关阅读:
    insightface数据制作全过程记录更新
    每日三题 10.20
    六级阅读3大核心技巧-因果关系题:如何识别因果
    ShardingSphere数据库读写分离
    自动化测试练手项目推荐
    【Vue全家桶】Vue-Router (详解)
    行为型:发布订阅模式
    TensorRT学习笔记(一)——使用Python API调用TensorRT
    大数据指标 透视50个DeFi头部协议
    Schillace 定律 背后的 Sam Schillace
  • 原文地址:https://blog.csdn.net/flin666/article/details/127422445