这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 嵌入式开发 » STM32 » 结构体中的字节对齐

共1条 1/1 1 跳转至

结构体中的字节对齐

院士
2026-03-18 18:21:30     打赏
字节对齐在c语言学习时就是一道非常经典的题目。在工程应用上,字节对齐也非常重要。最近我在硬件驱动开发时就遇到了一例字节对齐的问题,借论坛机会总结一下字节对齐的知识点。

我们的项目应用场景是硬件需要写入一段配置数据。于是,我们计划在M4中开辟了一块内存,作为配置数据的映射。简单示例一下硬件的配置数据。

硬件配置格式.jpg

对于内存开辟映射数据来说,可以直接使用uint8_t buf[11]的方式,但这里我们希望引用时更方便,所以此处使用结构体来实现:

typedef struct
{
    uint8_t type;
    uint8_t length;
    uint8_t cksum;
    uint8_t data[8];
} hw_type_a;

在实验中,数据结构满足要求,硬件也工作正常,但这里涉及到结构体字节对齐的一个典型概念。数组的起始地址是多少?是否满足四字节对齐?如果是。类型又如何呢?

知识点:结构体中的变量要遵循着取值规则:每个成员变量的起始地址必须是其自身大小的整数倍。

在前述结构体中,虽然有data[8]的空间申请,但其为uint8_t类型,单字节,故其起始地址紧邻着成员cksum。我们通过在Keil中编译并读取内存地址来查看

hw_a数据结构.jpg


其数据结构如果是下面这种数据结构申请的话呢?

typedef struct
{
    uint8_t type;
    uint8_t length;
    uint8_t cksum;
    uint32_t data[2];
} hw_type_b;

这时,成员变量uint32_t data[2]的起始地址就需要进行4字节对齐,带成员cksum后面必须填充一个padding来让对齐,从而满足uint32_t类型的4字节对齐要求。

hw_b数据结构.jpg


通过编译器的编译结果,我们也可以通过数据结构的长度[0]对应hw_a,[1]对应hw_b清晰得出上述结论。

hw数据结构字节长度.jpg

附上我的测试源代码:

#include <stdint.h>

typedef struct
{
    uint8_t type;
    uint8_t length;
    uint8_t cksum;
    uint8_t data[8];
} hw_type_a;

typedef struct
{
    uint8_t type;
    uint8_t length;
    uint8_t cksum;
    uint32_t data[2];
} hw_type_b;

uint32_t debug_reg_list[8] = {0};

hw_type_a hw_a;
hw_type_b hw_b;

int main(void)
{
    hw_a.type = 0x01;
    hw_a.length = 0x04;
    hw_a.cksum = 0x3E;
    hw_a.data[0] = 0x55;

    hw_b.type = 0x02;
    hw_b.length = 0x02;
    hw_b.cksum = 0x42;
    hw_b.data[0] = 0xAA;

    debug_reg_list[0] = sizeof(hw_type_a);
    debug_reg_list[1] = sizeof(hw_type_b);

    while (1)
    {
        ;
    }
}

最后,个人建议不要使用来强制对齐







关键词: 结构体     字节     对齐    

共1条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]