C语言中如何将struct结构体变量转换为uint8_t数组
问题原因
这个问题是C语言默认的结构体内存对齐机制导致的。为了提升内存访问效率,编译器会在结构体成员之间插入无意义的填充字节,保证每个成员的地址符合自身对齐要求。
你的结构体实际内存布局如下:
time(2字节)→lat(2字节)→ns(1字节)→ 1字节填充 →lon(2字节)→ew(1字节)→ 1字节填充(结构体整体对齐到2字节边界)
整个结构体的实际长度是10字节而非你预期的8字节,直接用memcpy拷贝会把无意义的填充字节也写入数组,甚至你的ew成员根本没有被拷贝到长度为8的数组里,所以结果不符合预期。
解决方法
方法1:手动序列化(推荐,跨平台通用)
手动逐个将结构体成员的字节写入数组,完全不受编译器对齐规则影响,还可以自主控制字节序,兼容性最高:
// 以下代码按小端序写入,和你原有memcpy的字节序逻辑保持一致 msg_arr[0] = (uint8_t)(msg.time & 0xFF); msg_arr[1] = (uint8_t)((msg.time >> 8) & 0xFF); msg_arr[2] = (uint8_t)(msg.lat & 0xFF); msg_arr[3] = (uint8_t)((msg.lat >> 8) & 0xFF); msg_arr[4] = msg.ns; msg_arr[5] = (uint8_t)(msg.lon & 0xFF); msg_arr[6] = (uint8_t)((msg.lon >> 8) & 0xFF); msg_arr[7] = msg.ew;
运行后得到的数组就是预期结果:[52, 18, 34, 33, 110, 52, 34, 101]。
方法2:取消结构体对齐
用编译器专属指令声明结构体为紧凑无填充布局,之后直接用memcpy即可:
GCC/Clang 环境:
typedef struct __attribute__((packed)) message_t { uint16_t time; uint16_t lat; uint8_t ns; uint16_t lon; uint8_t ew; } message;
MSVC 环境:
#pragma pack(1) typedef struct message_t { uint16_t time; uint16_t lat; uint8_t ns; uint16_t lon; uint8_t ew; } message; #pragma pack()
声明完成后直接调用memcpy(msg_arr, &msg, 8);即可得到正确结果。
内容的提问来源于stack exchange,提问作者lei lei
相关产品推荐
相关产品推荐

