指针强制转换and字节序导致的问题

       在C语言开发的过程中,发现不同硬件平台出现了一定差异性,例如在x86_64运行正常,二在xlp运行失败,分析如下。
       x86_64是小端序,而xlp是大端序。
       排查代码的时候,发现在相应申请内存的地方出现了强制转换。
       简化原来的代码如下:

DWORD FUNC_A(ULONG *pulMemSize)
{
    dwRet = FUNC_B ( (DWORD *)pulMemSize);
    return 0;
}

       其中DWORD为宏定义的unsigned int,而ULONG为unsigned long。由于FUNC_B为一个静态库提供的接口,同时入参为DWORD类型的指针。因此在这个地方进行了强制的转换。因为从ULOGN指针转换为DWORD指针,因此转换之后的DWORD指针的范围为pulMemSize这个指针所指向内存地址的前四个字节。
       来看一下变量内容是如何存储的。
       在小端序的系统(x86_64)中,如果*pulMemSize = ABCDEFGH,那么内存的存储顺序为HGFEDCBA(低地址存储变量低位),因此在进行指针转换的时候DWORD指针取值为HGFE,也就是说在 FUNC_B中对pulMemSize所指变量的操作是基于HGFE所在的内存空间,而由于HGFE所在的内存空间在小端序的系统中所表示的恰恰也是pulMemSize所指向变量的低位部分,因此这样操作是没有问题的(前提是取值没有超过32位大小)。
       但是在大端序的系统中,pulMemSize所指向变量的存储顺序为ABCDEFGH,而FUNC_B对pulMemSize所指变量的操作则是基于ABCD所在的内存空间,但是ABCD所表示的是pulMemSize所指向变量的高位部分。因此最后在以ULONG来取pulMemSize表示的内存值的时候,则会出错。
更新之后的代码为:

DWORD FUNC_A(ULONG *pulMemSize)
{
    DWORD dwMemSize = 0;
    dwRet = FUNC_B ( &dwMemSize);
    *pulMemSize = (ULONG)dwMemSize;
    return 0;
}

       可以看出这个dwMemSize这个中间临时变量作用大大的,因此以后如果见到这种看似没有的中间变量,不要轻易删除。
       其实这个问题说明的一个问题是,正常变量的强制转换。不同的硬件平台会自动的补齐或者截断对应的高位数据,但是对于指针的操作,由于指针总是从变量起始的位置开始寻址,因此要千万注意指针的强制转换。在不同的硬件系统可能会产生差异性。
       本文为CSDN村中少年原创文章,转载记得加上小尾巴偶,博主链接这里

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

村中少年

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值