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

    文章

    8651

    浏览量

    361819
  • 字节
    +关注

    关注

    0

    文章

    37

    浏览量

    13411
  • 代码
    +关注

    关注

    30

    文章

    4555

    浏览量

    66772
  • 结构体
    +关注

    关注

    1

    文章

    125

    浏览量

    10750
收藏 人收藏

    评论

    相关推荐

    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

    为什么ST库函数结构没加对齐地址是连续的?

    为什么ST库函数结构没加对齐,地址是连续的
    发表于 10-15 08:11

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

    01 默认字节对齐 C语言结构字节对齐是老生常谈的问题了,也是高频面试题,现在我们来深入研究这个问题,彻底弄懂到底是怎么回事,给你一个
    的头像 发表于 06-12 17:42 2824次阅读

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

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

    单片机开发重点-字节对齐问题

    (n),C编译器将按照n个字节对齐。使用伪指令 #pragma pack(),取消自定义字节对齐方式。另外,还有如下的一种方式:__attribute((aligned (n))),让
    发表于 11-13 13:06 6次下载
    单片机开发重点-<b class='flag-5'>字节</b><b class='flag-5'>对齐</b>问题

    STM32 终极字节对齐解析

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

    单片机字节对齐

    对齐原则:数据存放的地址需要是其类型长度的整数倍;字节对齐的作用不仅是便于cpu快速访问,同时合理的利用字节对齐可以有效地节省存储空间。许多
    发表于 12-01 15:21 11次下载
    单片机<b class='flag-5'>字节</b><b class='flag-5'>对齐</b>

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

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

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

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