C语言结构体内存布局为何不影响序列化/反序列化函数的正常运行?
手动计算序列化偏移量生效的原因解释
- 核心逻辑是你混淆了序列化目标缓冲区的偏移规则和C结构体自身的内存布局规则
serialize_row函数中的destination指针指向的是一块用于紧凑存储行数据的自定义连续内存,这块内存没有结构体对齐的强制要求,你手动计算的ID_OFFSET、USERNAME_OFFSET、EMAIL_OFFSET都是针对这块目标缓冲区的偏移量,和Row结构体本身是否存在对齐填充完全无关。 - 访问结构体成员时编译器会自动处理对齐逻辑
你从source(Row类型指针)中取成员地址时,使用的是&(source->id)、&(source->username)这类成员访问语法,C编译器会自动根据当前平台、当前编译参数的对齐规则,计算出每个成员在Row结构体内部的实际偏移,哪怕结构体成员之间存在填充,你拿到的成员地址也一定是准确的,不需要你手动计算结构体内部的偏移。 - 补充验证:你当前使用的
Row结构体本身确实不存在内部填充
按照gcc在x86、ARM平台的默认对齐规则:uint32_t的对齐要求为4字节,char类型的对齐要求为1字节。第一个成员id占4字节,后续的username、email都是char数组,对齐要求为1,所以成员之间不需要插入填充字节。你可以引入<stddef.h>头文件,通过offsetof(Row, username)、offsetof(Row, email)打印实际偏移验证,结果和你手动计算的4、36完全一致。不过这只是当前结构体的特性,哪怕你换用存在内部填充的结构体,只要还是通过->语法访问成员拷贝数据,这套序列化逻辑依然可以正常运行。
内容的提问来源于stack exchange,提问作者RobJob
相关产品推荐
相关产品推荐

