一次数组越界的Bug经历

发表于:2018-5-21 11:01

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:Andrew_qian    来源:博客园精华区

  数组和指针都是C里面的好东西,但是一旦使用不当,真的会让人抓狂。
  下面是写程序时遇到的一次数组越界的经历,感觉对以后写程序有点启发,所以记录下来。
  起因:
  我想用OLED动态显示一组浮点数,而且浮点数的长度是不定的。
  1、如果只是单纯的显示,没有消隐的话,上一次的长数的据残留会影响下一次短长度数据的显示。
  2、如果显示一次就清空一次显示区域的话,数据会一直抖动,一开始以为是我刷新频率不够,故把刷新频率由100HZ改为1000HZ,但是效果还是和之前一样!
  后来想想也是,不管我把刷新频率改为多少,清空后的空白和显示的数据都是相同的频率。1000hz显示数据,那么也是1000hz的空白。所以会抖动严重。
  3、把数据的每一位都取出来单独显示,但是这样就又带来了数据对齐的问题。不爽,不好看,弃之。
  4、使用sprintf格式化需要显示的数据为字符串。然后用OLED的显示字符串的方式显示。
  于是有了下面这样的程序:
sprintf((char *)weight_string,"%.1f",weight);        //格式化为字符串
Clear_Left_Num(money_string);                                //消除残余
OLED_Show_String(42,2,weight_string);
sprintf((char *)price_string,"%d",price);
Clear_Left_Num(money_string);
OLED_Show_String(42,4,price_string);
  这段程序在定时器中断函数中调用。weight 和 price 就是我想显示的浮点数。
  先格式化为字符串,然后显示。OLED_Show_String() 的前两个参数是字符的起始显示坐标。
  Clear_Left_Num 函数如下:
void Clear_Left_Num(unsigned char *num_string)
{
while(*num_string != '.')
num_string++;
//一位小数点后面的数据用空格刷新
*(num_string+2) = ' ';
*(num_string+3) = ' ';
*(num_string+4) = ' ';
}
  思路就是把小数点后一位后面的残余数据用空格刷新。
  但是实验现象是在显示完第一行数据之后,本来应该在第二行显示第二个数据,但是他 在第一行数据的后面又显示了第二行的数据!!也就是说第二行数据显示了两次。
  为什么会显示两次呢?我程序中就写了一次啊、、、
  分析:
  既然是显示的问题,那就先看看这个显示函数!
/*----------------------------------
**函数名称:OLED_Show_String
**功能描述:光标处显示字符串,字符串可以用数组表示,unsigned char string_2[] = {"THIS IS A TEST  "};
**参数说明:X,Y为坐标
* chr:字符串首地址
**作者:Andrew
**日期:2018.1.24
-----------------------------------*/
void OLED_Show_String(u8 x, u8 y, u8 *chr)
{
u8 j=0;
while (chr[j]!='\0')
{
OLED_ShowChar(x,y,chr[j]);
x+= 8 ;
if(x>120){x=0;y+=2;}  //自动换行写
j++;
}
}
  原来这个函数会在数组结束之前,显示数组的全部内容。因为数组的最后一个结尾标志是  '\0’
  那么,上面第一行一直在显示,说明他可能没有遇到数组结束标识符。
  查看数组定义的大小:
  unsigned char weight_string[7] = {0};
  unsigned char price_string[3] = {0};
  原来 weight_string 数组的最后一个结束标志被我赋值成了空格。那么他就会一直读取存储在这个数组后面的内存数据,并且给显示出来。也就是所谓的“数组越界”。
  幸好我们只是读取显示,并没有改写这个数据!
  既然他显示的是第二行的数据,说明第二行的数据就是存储在在这个数组后面的内存中。
  查看编译器生成的map文件:
  果然,第二个数组紧邻着第一个数组存储。
  第一个数组读取越界之后,读到了第二个数组。
  到此,问题解决。
  总结:
  一定要看到程序的内在联系。分析内存虽然困难,但是却是找到烦人bug 的捷径。

上文内容不用于商业目的,如涉及知识产权问题,请权利人联系博为峰小编(021-64471599-8017),我们将立即处理。
《2023软件测试行业现状调查报告》独家发布~

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号