• 指针大小比较问题


    今天遇到一个问题,系统有时执行正确,有时执行错误。关键代码如下

    TYPE *res = NULL;

    TYPE mydata;

    res = search(arg1, arg2,  &mydata);

    if(res <= 0)

    {

      printf("search return value is not valid!!!!! ");

      return -1;

    }

    其中,search函数的大致过程如下:

    TYPE *search(int arg1, int arg2, TYPE *data_ptr)

    {

      if(...)

      {

        if(...) return 0;  

        else if(...) return -1;

      }

      else

      {  

        data_ptr->.. =..;

        return data_ptr;

      }

    }

    按照楼主的想法,search执行出错时,返回值为非正值。执行成功,返回正值,因为地址一定非负。

    但是程序运行过程中对于同样的参数输入,search有时返回值为非正值,有时为正值,楼主自然以为search函数的返回值很可能被破坏掉了,导致时好时坏。

    折腾了一天,又是添加printf语句又是对指针强制类型转换的,最后都没有解决问题。

    后来,一个同事过来看了看,让我改变判断条件。将对返回值的判断改为下列语句:

    if(-1 == res || 0 == res)

    {

      printf();

      return -1;

    }

    做了这样的修改后,程序奇迹般的不再出现时好时坏的情况了。此时楼主恍然大悟,即使search执行正确,返回值也有可能是非正值。 

    因为,返回值是个变量地址。 

    学过操作系统的人都知道,程序执行过程中用到的地址都是虚拟地址,是由操作系统经内存映射生成的。 理论上讲,这些地址可以是指针类型大小所能表示的任意值。对于32位机器而言,这个值的变化范围为0~0xFFFFFFFF;对于64位机器而言,这个值变化范围为0~0xFFFFFFFFFFFFFFFF。 所以,变量的地址可以是程序所在平台的任意值。

    楼主的机器是64位机,指针类型变量大小也为64位,int型变量大小为32位。

    考虑以下情况,

    (1)mydata变量的地址为0x0000FFFF89765431, 当与0相比较时,比较运算符会自动识别变量类型,并会对变量两边类型自动进行转换,如类型提升。 此时,res的值确实大于0,但如果将改值强制转换为int型后再与0相比较,就会得出小于0的结果。

    原因在于,64位机器上指针类型大小为64位,int型大小为32位,这种强制类型转换会导致高32位丢失,得到的值实际上为0x89765431。 最高位是1,且为int型,所以小于0。

    (2)mydata变量的地址为0xF0000720005674A6, 当与0相比较时,比较运算符为64位数之间的“无符号比较”,地址也为正值。由此,当mydata为-1时,此时它的十六进制表示为0xFFFFFFFFFFFFFFFF, 由于指针和整数直接比较时指针被视为无符号整数,故此时mydata实际为最大整型值,if判断不成立。

     

    通过以上分析,采用对search不同情况下的返回值进行判断,而不是将非正值视为search执行失败的情况,只要变量地址不为NULL且为0xFFFFFFFFFFFFFF,则一定可以保证if判断语句的正确性。

    总结原来程序失败原因,有下:

    (1)对指针值与整型比较时,指针值的类型不清楚,经验证,楼主的64位机将指针及与指针相比较的数视为无符号长整型。

    (2)相当然的认为指针值不会超过32位。64位机,指针可以为0~0xFFFFFFFFFFFFFFFF间的任意值。用int型强制转换会引起精度丢失。

    (3)没有对search的返回值进行详细利用,无意间扩大了返回值的代表的信息。 原本search对返回0和-1的情况认为是失败情况,而楼主将其扩大为所有非正值都是失败情况,这是引入错误的根源。

     

    经过这番过程,楼主深深的感到,学问还需仔细推敲,不是相当然就可以的。 谨以此记告诫自己和如楼主一样粗心大意的IT工作者们,编程还是要有扎实的基本功和良好的推敲习惯,正所谓 纸上得来终觉浅,绝知此事要躬行!

  • 相关阅读:
    [Javascript] Use a custom sort function on an Array in Javascript
    [Unit Testing] Fundamentals of Testing in Javascript
    [WASM] Create a New Rust/Webpack Project using the rust-webpack Template
    [Adobe Analytics] Segments types
    win7系统远程连接其它计算机,并且向远程机传输文件
    移动应用数据统计分析平台汇总
    设计模式(策略模式)
    程序员与卓别林
    我的Android进阶之旅------>HTTP 返回状态值详解
    OSX: 真的吗?Mac OS X重大漏洞 改时钟获系统最高权限
  • 原文地址:https://www.cnblogs.com/isrc/p/3612431.html
Copyright © 2020-2023  润新知