交接项目的时候遇到的一个问题,涉及指针、字节序、结构体内存对齐相关知识,三大知识包含规则的共同作用导致了这一问题。
问题描述
时间有些久远了,结合下图来讲,总之,就是变量 vsys_id
莫名其妙地被更改了。当时检查了可能出现问题的相关函数,以及函数传参过程,均没有发现问题所在,甚至在这些地方连 vsys_id
变量名都没有出现,以至于一直没能定位问题。最后发现 vsys_id
被脏数据写入了,也就是说,我们更改变量 policy_id
的同时把 vsys_id
也给改了,从而导致了问题。
问题分析
根据结构体内存对齐画出结构,可以发现 vsys_id
和 policy_id
是紧挨着的。原先指向 policy_id
的指针是 u16 *
,原代码对其进行了一个强转成 u32 *
的操作,这样一来,这个指针就指向了 policy_id
加 vsys_id
的4个字节,然后原代码对该指针取值赋值1,相当于把这4个字节当成一个变量赋值了。这里似乎是由于传参的时候类型不匹配,于是使用了强转,具体为什么要强转也记不太清了。总之按照正常的逻辑,代码其实是要对 policy_id
赋值成1。强转后赋值的情况如图所示,在X86架构下,的确只是对 policy_id
赋值成1,没什么不对的,所以测试的时候X86架构没啥问题;在MIPS架构下,由于字节序相反,1反而是写给了 vsys_id
,从而引发了问题。
结构体内存对齐这里不赘述,简单来说就是:
成员的偏移量要是自身大小的整数倍,
结构体总大小要是最大成员大小的整数倍。
至于字节序,图中描述已经很清楚。
本来是给 policy_id
赋值,却同时改掉了相邻的 vsys_id
的值,也难怪乍一看定位不了问题。最后理解了问题成因,也就顺利解决了。本文对导致该问题的原因做一个记录。