Chinaunix首页 | 论坛 | 博客
  • 博客访问: 21682
  • 博文数量: 9
  • 博客积分: 226
  • 博客等级: 二等列兵
  • 技术积分: 105
  • 用 户 组: 普通用户
  • 注册时间: 2012-03-07 16:24
文章分类
文章存档

2012年(9)

我的朋友

分类: BSD

2012-04-12 14:57:11

问题描述:
 
今天在测试过程中发现一个现象:
从网络收到一个包, 此包为一个结构体,各个字段在下图中用竖线标识
 
head
|--id--|---name---|--len--|---other----|
 
原本收到包后,按照结构体head->取各个成员值,但发现取出的值是错误的
 
30     32         3b      40              <-Address     
|--id--|---name---|--len--|---other----|
 
后来发现用head->len取值时, head->len并未从3b的地址取,而是从后面的一位也就是3c地址开始取值
 
回顾一下结构体定义:


  1. typedef struct _ha_packet {
  2.     uint16_t type;
  3.     uint8_t name[HA_UNIT_NAME_MAX + 1]; /* unit name*/
  4.     uint16_t len; /*not include head*/
  5.     uint8_t data[HA_PACKET_DATA_MAX_LEN];
  6. }...
成员均为uint8_t, uint16_t类型定义。
结构体对齐按照uint16_t类型长度也就是2字节对齐。
上面的name成员长度为9,但是也正因为按照2字节对齐,实际上结构体中的name成员是占了10个字节,也就是说,结构体认为len和name之间占了10个字节,访问len时会从第11个字节开始访问。
 
而发来的报文中name只占9字节,第10字节开始是len的成员。
 
这种结构体和数据的不一致导致结构体访问错误。
 
改正方法:
可以在结构体定义前后分别加
#pragma pack(1)
...
#pragma pack()
 
强制让结构体按照1字节对齐
阅读(1148) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~