带位域的Packet结构体GDB内存dump与初始化预期不符的疑问
自定义网络协议Packet结构体的内存布局疑问
我为自定义网络协议设计了如下Packet结构体:
typedef struct { uint8_t src; uint8_t dest; uint8_t len; uint8_t flag; //位域是从右到左分配?gcc似乎还合并了字段? uint8_t type :4; uint16_t seq :12; // 该字段使用12位。小端序下[F3|02] == 0x02F3? uint8_t checksum; }Packet;
基于我对位域和结构体填充的理解,结构体的每个字段会连续存储(seq会从新的字节边界开始),而且我的设备是x64架构,不会有尾部填充。我预想的内存布局是:|src|dest|len|flag|type| seq |checksum|,整体是64位的头部,没有结构体填充。
为测试数据包的序列化,我用以下代码初始化了一个Packet实例:
thispack.src = 0x07; thispack.dest = 0x34; thispack.len = 0x5F; thispack.flag = 0xA2; thispack.type = 0x05; thispack.seq = 0xAED; thispack.checksum= 0x23;
我的系统是小端序,预期结构体的内存布局应该是:0x07 0x34 0x5F 0xA2 0x05 0xED 0x0A 0x23
其中seq的字节按小端序规则反转(因为0xAED的小端存储是0xED 0x0A)。
但在gdb中执行x/8bx &thispack后,得到的实际内存内容是:0x07 0x34 0x5f 0xa2 0xd5 0xae 0x23 0x00
我完全无法理解0xD5和0xAE是如何得到的,这甚至让我怀疑通过.符号访问结构体字段的正确性。我认为正确的情况应该是:
- 执行
uint8_t mytype = thispack.type时,mytype的值应该是0x05 - 执行
uint16_t myseq = thispack.seq时,对应内存中的字节应该是0xED 0x0A(小端序存储0xAED)
我实在想不通为什么会出现这样的结果。
内容的提问来源于stack exchange,提问作者6charm
相关产品推荐
相关产品推荐

