• C语言,关于字节对齐的一些问题


    字节对齐,依据的是当系统要访问特定类型的变量时,必须在特定的内存地址访问,这就要求各种类型的变量按照一定的规则在空间上排列,而不是顺序的逐个排放。其本质就是,字节对齐可以提升存取效率,也就是空间换时间

    为什么要字节对齐

    之前博主有研究过这个字节对齐相关的问题,欢迎大家来一同讨论!
    链接直通车:STM32解决读写Flash失败进入HardFault的问题

    每个平台对数据存放的对齐要求都不同,如果不按照适合该平台的数据存放对齐要求,会造成存取效率上的损失。比如某个平台每次读取数据时都是从偶地址开始的,如果一个int类型(32位系统)变量存放在偶地址开始的地方,那么一个读周期就能读出这32bit数据,而如果该变量存放在奇地址开始的地方,那么就需要两个读周期,并且要对这两次读出的结果进行高低字节拼凑才能得出这32bit数据,明显在读取效率上就低了很多。

    举个例子来说明这个字节对齐的问题

    背景知识:
    1、基础数据类型的自身对齐值(32位系统)
    char类型自身对齐为1字节,short类型自身对齐为2字节,int、float、long类型自身对齐均为4字节,double类型自身对齐为8字节。

    2、结构体或类的自身对齐值
    其成员中自身对齐值最大的值。

    3、指定对齐值
    通过预编译指令 #pragma pack (value)来指定对齐值的大小value,取消自定义对齐值使用 #pragma pack()。

    4、数据成员、结构体和类的有效对齐值
    其自身对齐值和指定对齐值中较小的那个值。

    例子1:如下两个结构体A、B

    struct A
    {
    	char a;
    	short b;
    	int c;
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    struct B
    {
    	short b;
    	int c;
    	char a;
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    请问上面两个结构体的大小分别是多少?
    答:对于结构体A和结构体B,a是char类型,占用1字节;b是short类型,占用2字节;c是int类型,占用4字节。因此结构体A和结构体B的自身对齐值为4字节。又因为结构体类型数据是按照顺序存储结构逐个向后排列的,因此结构体A的大小为8字节,结构体B的大小为12字节。其对应的存储方式如下图。
    在这里插入图片描述 在这里插入图片描述
    例子2:为C、D结构体指定对齐值

    #pragma pack(2) //指定2字节对齐
    struct C
    {
    	char a;
    	int b;
    	short c;
    };
    #pragma pack() //取消指定对齐,恢复缺省对齐
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    #pragma pack(1) //指定1字节对齐
    struct D
    {
    	char a;
    	int b;
    	short c;
    };
    #pragma pack() //取消指定对齐,恢复缺省对齐
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    请问上面两个结构体的大小分别是多少?
    答:对于结构体C,由于其自身对齐值为4字节,而指定对齐值为2字节,所以该结构体的有效对齐值为较小的2字节,因此结构体C的大小为8字节。对于结构体D,同理可以得知大小为7字节。其对应的存储方式如下图。
    在这里插入图片描述 在这里插入图片描述
    总结,整个程序在给每个变量进行内存分配时都遵循字节对齐原则,虽然这会造成内存空间的浪费,但是却能换来程序执行效率的提升。

  • 相关阅读:
    Excel第28享:如何新建一个Excel表格
    高级深入--day28
    EL表达式 Jstl (附上代码理解)
    k8s部署python3项目
    微信小程序-绑定数据并在后台获取它
    前端模块化
    【简说八股】Redisson的守护线程是怎么实现的
    高斯公式证明
    springcloud学习笔记:使用gateway实现路由转发
    第七章:面向对象编程(中级部分)
  • 原文地址:https://blog.csdn.net/Romeo_tune/article/details/125401028