串口传输结构体:需要考虑结构体对齐的问题#pragma pack (1)

张开发
2026/4/10 4:40:11 15 分钟阅读

分享文章

串口传输结构体:需要考虑结构体对齐的问题#pragma pack (1)
串口传输结构体需要考虑结构体对齐的问题否则会有多出一些乱七八糟的的数据。#pragma pack(1)99% 的场景都是用在结构体上核心作用就是取消字节对齐让结构体内存紧凑、无空隙、无冗余。一、#pragma pack (1) 到底是干嘛的一句话让结构体成员之间 “紧贴排列”不插入任何填充字节内存对齐空隙。默认情况下C 编译器会对结构体做字节对齐目的是让 CPU 读取更快但会浪费内存。#pragma pack(1)就是强制1 字节对齐 不浪费任何空间。二、默认对齐不用 pack会产生什么问题看这个结构体struct Test { char a; // 1 字节 int b; // 4 字节 short c; // 2 字节 };默认对齐下大小 12 字节但实际有效数据只有142 7 字节浪费了5 字节填充内存布局是这样的a [填充3] b c [填充2] 1B 3B 4B 2B 2B这就是数据冗余。三、加上 #pragma pack (1) 之后#pragma pack(1) // 1字节对齐 struct Test { char a; int b; short c; }; #pragma pack() // 恢复默认对齐大小 142 7 字节没有任何填充没有任何冗余内存布局a b c 1B 4B 2B四、为什么要用 #pragma pack (1)最关键主要用在 3 种场景1.串口 / 网络 / 蓝牙 通信协议发送方和接收方必须结构体内存布局完全一致不能有填充字节否则解析错误。2.读写 Flash / 文件要保证结构体大小固定不因为编译器不同而变化。3.节省内存嵌入式特别常用单片机 RAM 很小必须紧凑存储。五、正确写法必须会#pragma pack(1) // 开启1字节对齐 struct MyData { uint8_t head; uint16_t len; uint32_t data; }; #pragma pack() // 关闭恢复默认对齐一定要成对使用否则会影响后面所有结构体。

更多文章