0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看威廉希尔官方网站 视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

什么是结构体的字节对齐现象

麦辣鸡腿堡 来源:轩哥谈芯 作者:义轩 2023-11-20 15:55 次阅读

什么是结构体的字节对齐现象

程序员,咱都用代码说话,先上 code:

(说明:以下代码均在 ARM 平台上,使用 Keil 进行编译测试)

#define offset_of(TYPE, MEMBER) ((size_t) &((TYPE *)0)-MEMBER) //上面这个宏定义主要用于显示结构体成员变量相对结构体起始地址的偏移
typedef structstu1{ int a; char b; int c;}stu1;
void main(){ LOG_INFO("rnrn====== Struct Test ======rnrn"); LOG_INFO("offset_of(stu1,a):t%dn",offset_of(stu1,a)); LOG_INFO("offset_of(stu1,b):t%dn",offset_of(stu1,b)); LOG_INFO("offset_of(stu1,c):t%dn",offset_of(stu1,c)); LOG_INFO("sizeof(stu1) :t%dn",sizeof(stu1)); return ;}

图片

对于上面的运行结果,对字节对齐不了解的同学可能会疑惑,c的偏移量怎么会是8呢?不应该是 5 吗?

结构体的大小怎么会是12呢?不应该是 9 吗?

不了解的同学可能会这样理解:

c的偏移量是sizeof(int)+sizeof(char) = 5

结构体stu1占用的内存大小应该是sizeof(int)+sizeof(char)+sizeof(int)=9。

通过下图所示的stu1的内存结构可以知道,编译器对变量存储进行了一个特殊处理。

图片

为了提高CPU的存储速度,编译器对一些变量的起始地址做了对齐处理。

在默认情况下,编译器规定各成员变量存放的起始地址相对于结构体的起始地址的偏移量,必须为该变量的类型所占用的字节数和编译器编译过程中采用的字节对齐数两者中最小值的整数倍。

有点绕,比如stu1 结构体中,变量 c 类型为 int,也就是占用 4 字节,编译器采用 4 字节对齐,因此偏移量必须是 4 的整数倍。

typedef structstu2{    int a;    char b;    char c    int d;}stu2;

再比上面的 stu2中,如对于变量 c,其类型为 char ,占用 1 字节,编译器采用 4 字节对齐,因此 它被分配的偏移量需要是 1 的整数倍,在上面的结构体 stu2 中,c 的偏移量为 5。

如图:

图片

现在来分析前面的代码

假定a的起始地址为0,它占用了4字节,接下来的空闲地址就是4,是1的倍数,满足要求,所以b存放的起始地址是4,占用一个字节,接下来的空闲地址为5。c也是char变量,占用1字节, 因此可以放在地址 5 上面。

接下来看地址 6,对于 d,它占用了 4 个字节,同时需要注意的是,编译器默认按照结构体中占有内存最大的类型所占用的字节数进行字节对齐。在此结构体中占用内存最大的为整型,占用4字节,所以在此取两者的最小值4,6 并不是4的整数倍,所以向后移动,找到离6最近的8作为存放d的起始地址,d也占用4字节,最后结构体的大小为12。

需要注意的就是,变量b和 c后面2字节的存储空间是由编译器自动填充的,其中没有存储任何有用的信息

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • ARM
    ARM
    +关注

    关注

    134

    文章

    9087

    浏览量

    367403
  • 字节
    +关注

    关注

    0

    文章

    40

    浏览量

    13727
  • 代码
    +关注

    关注

    30

    文章

    4780

    浏览量

    68530
  • 结构体
    +关注

    关注

    1

    文章

    130

    浏览量

    10840
收藏 人收藏

    评论

    相关推荐

    C语言-结构对齐详解

    ", sizeof (struct mystruct1));// sizeof (struct mystruct1) = 8} 分析:整个结构变量4字节对齐是由编译器保证
    发表于 07-12 16:41

    RM48HDK平台CCS结构字节对齐总是咨询

    硬件平台:RM48HDK  软件平台:5.4.0.00091  编译器:TI V5.0.6 我在程序中想对一个结构增加单字节对齐属性,增加方式如下: 1、参照《ARM Optimiz
    发表于 05-25 10:38

    CCS3.3 结构成员对齐

    : expected a type specifier error: expected a ";" 这个错误。是CCS3.3编译器本身不支持__packed这种结构成员的对齐方式
    发表于 06-21 10:16

    请问在ccs4.2 中怎么设置结构字节对齐

    请问在ccs4.2 中怎么设置结构字节对齐,用于网络数据发送的。是:]__attribute__((packed))还是:#pragma pack(1)编译后,两种都不行,是什么原
    发表于 08-02 07:47

    请问z-stack结构默认对齐方式是一字节吗?

    z-stack的结构默认对齐方式是一字节吗?在z-stack中可以将一般指针强制转换为结构
    发表于 08-18 07:38

    请问cc2640r2 ccs7.4结构字节能实现对齐吗?

    请问结构字节下面能实现字节对齐么#pragma pack(1)typedef struct [ uint16_t nt ; uint8_t
    发表于 10-31 10:10

    STM32终极字节对齐的相关资料推荐

    字节对齐。uint64_t定义变量地址要8字节对齐。指针变量是4字节对齐。二、
    发表于 12-06 06:03

    解析C语言结构字节如何对齐

    01 默认字节对齐 C语言结构字节对齐是老生常谈的问题了,也是高频面试题,现在我们来深入研究这
    的头像 发表于 06-12 17:42 3069次阅读

    C语言中Linux字节对齐的问题

    ,于是经过排查,是因为传递消息的结构没有考虑字节对齐的问题。 随手整理一下C语言中字节对齐的问
    的头像 发表于 08-16 11:25 2482次阅读
    C语言中Linux<b class='flag-5'>字节</b><b class='flag-5'>对齐</b>的问题

    STM32 终极字节对齐解析

    字节对齐。uint64_t定义变量地址要8字节对齐。指针变量是4字节对齐。二、
    发表于 11-23 18:06 11次下载
    STM32 终极<b class='flag-5'>字节</b><b class='flag-5'>对齐</b>解析

    结构对齐理解上有点偏差

    总结一下: 结构对齐不再是简单的字节个数的拼凑,而是要与内存地址进行挂钩~一般我们也可以理解为内存地址分配是多少字节的倍数,就是多少直接
    的头像 发表于 08-10 18:08 1198次阅读
    对<b class='flag-5'>结构</b><b class='flag-5'>体</b>的<b class='flag-5'>对齐</b>理解上有点偏差

    结构对齐为什么那么重要?

    以前我也没觉得懂得这个结构对齐或者内存对齐有多重要,直到已经从事了嵌入式开发经验不断积累,才慢慢体会到,这是一种很基础的知识,就因为这个东西不常用,而出现相关的问题是非常致命的,排查
    的头像 发表于 04-03 10:13 1395次阅读

    为什么要结构对齐?为什么结构对齐那么重要?

    C语言结构对齐问题,是面试必备问题。我参与招聘威廉希尔官方网站 面试的时候,也喜欢问这个威廉希尔官方网站 点。
    的头像 发表于 05-26 14:10 1258次阅读
    为什么要<b class='flag-5'>结构</b><b class='flag-5'>体</b><b class='flag-5'>对齐</b>?为什么<b class='flag-5'>结构</b><b class='flag-5'>体</b><b class='flag-5'>对齐</b>那么重要?

    嵌套的结构 字节是如何对齐

    嵌套的结构字节又是如何对齐的呢 先来看下面的代码 typedef struct stu1 { char ary [ 5 ] ; int a; }stu1; typedef stru
    的头像 发表于 11-20 16:01 525次阅读
    嵌套的<b class='flag-5'>结构</b><b class='flag-5'>体</b> <b class='flag-5'>字节</b>是如何<b class='flag-5'>对齐</b>的

    keil arm工程中结构1字节对齐如何实现

    的默认对齐方式和规则 结构在Keil Arm工程中的默认对齐方式是根据编译器或者编译器选项来定的。通常情况下,编译器会按照平台的特定对齐
    的头像 发表于 01-05 14:40 3759次阅读