指针操作,让我吃了一次亏

来源:互联网 发布:淘宝装修 代码大全 编辑:程序博客网 时间:2024/04/29 21:32

记录一下自己的心得,毕竟是2009年的最后一天了。

在这个特殊的一天里,我竟然修一个BUG修了一天。。。杯具啊

 

BUG属于内存被非法改写的类型,最后我利用逐步添加代码模块逐步排除的方法找出了罪魁祸首。嘿嘿

大概那段代码如下:

{              //unicode转ascii
                UINT32    Len_str = 0;
                UINT32    Len_str_bk = 0;
                UINT32    Length = 0;
                UINT32    pos = 0;
               
                U16        *pText = (U16 *)EsrResult.pItemText;
                Len_str = iToystrlen((U16 *)EsrResult.pItemText);
                Len_str = Len_str<<1; //2倍
                Len_str_bk = Len_str;
                memset(&Esr_pTextAscii_Buffer[0], 0, sizeof(Esr_pTextAscii_Buffer));
                while(Len_str != 0)
                {
                    Length = __uni2ascii(*pText++, &Esr_pTextAscii_Buffer[pos]);
                    pos += Length;
                    Len_str -= Length;
                }

                Esr_pTextAscii_Buffer[Len_str_bk] = '/0';
                ASSERT(pos == Len_str_bk);
}

代码思路解释一下:

从识别引擎返回的结果EsrResult.pItemText是unicode-16的,我现在需要把它转化为ascii字符之后输出到TXT文件中,

我事先定义了一个内存Esr_pTextAscii_Buffer[100]来存放转换过后的ascii字符(这个空间是够大的)。

 

问题出来了,请注意红色部分,仔细一琢磨,这是有风险的。判断条件为 Len_str != 0,再看后面的Len_str -= Length.这里就是出问题的地方

正常情况下,Len_str -= Length 减到最后应该正好等于0,但是在某种情况下,可能Len_str = 1, 而Length = 2, 得到的结果为 -1,而

Len_str是 unsigned int 型的,所以它的值编成了最大的 0xFFFFFFFF,这就正好导致循环条件不会被中止,一直循环下去,而在循环体里

正好又是对某段特定的内存读写操作,可想而知,肯定产生了对其他位置内存上数据的改写,而改写的如果正好是重要数据的话,系统崩溃。

 

好了,如果解决了,初步想到的是,判断条件改成 while( Len_str != 0 && Len_str < Len_str_bk)

 

原创粉丝点击