一次数组越界的bug经历
数组和指针都是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(,,weight_string); sprintf((char *)price_string,"%d",price);
Clear_Left_Num(money_string);
OLED_Show_String(,,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+) = ' ';
*(num_string+) = ' ';
*(num_string+) = ' ';
}
思路就是把小数点后一位后面的残余数据用空格刷新。
但是实验现象是在显示完第一行数据之后,本来应该在第二行显示第二个数据,但是他 在第一行数据的后面又显示了第二行的数据!!也就是说第二行数据显示了两次。
为什么会显示两次呢?我程序中就写了一次啊、、、
分析:
既然是显示的问题,那就先看看这个显示函数!
/*----------------------------------
**函数名称: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=;
while (chr[j]!='\0')
{
OLED_ShowChar(x,y,chr[j]); x+= ; if(x>){x=;y+=;} //自动换行写 j++;
}
}
原来这个函数会在数组结束之前,显示数组的全部内容。因为数组的最后一个结尾标志是 '\0’
那么,上面第一行一直在显示,说明他可能没有遇到数组结束标识符。
查看数组定义的大小:
unsigned char weight_string[] = {};
unsigned char price_string[] = {};
原来 weight_string 数组的最后一个结束标志被我赋值成了空格。那么他就会一直读取存储在这个数组后面的内存数据,并且给显示出来。也就是所谓的“数组越界”。
幸好我们只是读取显示,并没有改写这个数据!
既然他显示的是第二行的数据,说明第二行的数据就是存储在在这个数组后面的内存中。
查看编译器生成的map文件:
果然,第二个数组紧邻着第一个数组存储。
第一个数组读取越界之后,读到了第二个数组。
到此,问题解决。
总结:
一定要看到程序的内在联系。分析内存虽然困难,但是却是找到烦人bug 的捷径。
一次数组越界的bug经历的更多相关文章
- iOS如何彻底避免数组越界
我们先来看看有可能会出现的数组越界Crash的地方: ? 1 2 3 4 5 6 7 - (void)tableView:(UITableView *)tableView didSelectRowAt ...
- Objective-c防止数组越界而崩溃(全局效果)
数组越界其实是很基本的问题,但是解决起来除了count的判断,还有每个调用的时候都要去判断一遍 对于不明确的数据总会有崩溃的风险 然而 每次调用都判断 那是太累了 so ..runtime&c ...
- 数组越界保护与消息传递black机制
数组越界保护if(index.row <= [array count]) 发送消息[[NSNotificationCenter defaultCenter] postNotificati ...
- 解决Android时时更新listview数组越界问题
时时更新数据一般出现在金融.股票行业对数据的准确性要求极高情况下使用. 先来看看下面一段代码, public class MainActivity extends Activity { private ...
- Android 【问题汇总】列表数组越界的问题
遇到了一个诡异的问题,ListView发生数组越界(偶尔会),程序崩溃. 错误信息如下: W/dalvikvm( ): threadid=: thread exiting with uncaught ...
- iOS 数组越界 Crash加工经验
我们先来看看有可能会出现的数组越界Crash的地方. - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSInd ...
- Java中的数组越界问题
Java中数组初始化和OC其实是一样的,分为动态初始化和静态初始化, 动态初始化:指定长度,由系统给出初始化值 静态初始化:给出初始化值,由系统给出长度 在我们使用数组时最容易出现的就是数组越界问题, ...
- java.sql.SQLException之数组越界
java.sql.SQLException之数组越界 1.具体错误如下: (1)java.sql.SQLException:Parameter index out of range(0<1) ( ...
- .NET 下 模拟数组越界
前面一篇文章提到过 数组越界行为,虽然编译器为我们做了大量的检查工作让我们避免这些错误. 但是我觉得还是有必要模拟一下数组越界,感受一下这个错误. 那么对于.NET来说我们怎么来模拟数组越界呢? 一. ...
随机推荐
- OpenCV矩阵运算
矩阵处理 1.矩阵的内存分配与释放 (1) 总体上: OpenCV 使用C语言来进行矩阵操作.不过实际上有很多C++语言的替代方案可以更高效地完成. 在OpenCV中向量被当做是有一个维数为1的N维矩 ...
- "《算法导论》之‘线性表’":基于动态分配的数组的顺序表
我们利用静态分配的数组来实现的顺序表的局限还是挺大的,主要在于它的容量是预先定好的,用户不能根据自己的需要来改变.如果为了后续用户能够自己调整顺序表的大小,动态地分配数组空间还是很有必要的.基于动态分 ...
- PhotoShop 图像处理 算法 汇总
不定期更新 ...... 直接点标题即可链接到原文. OpenCV 版:OpenCV 图像处理 图层混合算法: PS图层混合算法之一(不透明度,正片叠底,颜色加深,颜色减淡)PS图层混合算法之二(线性 ...
- PS 滤镜算法原理——碎片效果
%%% Fragment %%% 对原图做四个方向的平移,然后对平移的结果取平均 %%% 碎片效果 clc; clear all; Image=imread('4.jpg'); Image=doubl ...
- Unity修改Particles Render Material(Unity3D开发之二十三)
猴子原创,欢迎转载.转载请注明: 转载自Cocos2Der-CSDN,谢谢! 原文地址: http://blog.csdn.net/cocos2der/article/details/48372999 ...
- HBase Compaction
当 client 向 hregion 端 put() 数据时, HRegion 会判断当前的 memstore 的大小是否大于参数hbase.hregion.memstore.flush.size 值 ...
- Sencha touch 2 入门 -------- DataView 显示服务器端JSON文件数据
今天学习了下DataView如何显示JSON文件数据,废话不多说,直接贴代码: 首先看下文件目录: 然后看下我们要处理的JSON文件,bookInfo.json. { "success&qu ...
- nasm预处理器(3)
nasm提供一个限定符.nolist,可以包含它到一个宏定义中,这样该宏就不会在列表文件中被展开:限定符 .nolist直接放到参数后面: %macro foo 1.nolist 条件汇编 和C预处理 ...
- Hibernate与Mybatis的比较
Hibernate与Mybatis的比较: Hibernate: 标准的.重量级.全自动化的ORM框架 可以写sql(SQLQuery,sql )也可以不写sql(Query,hql) ORM映射主要 ...
- 使用IntelliJ IDEA的小技巧快乐编程(2)
前言 本篇介绍的技巧为IntelliJ IDEA中自动代码生成相关的技巧,合理的使用这些技巧将大大提高的你的编码效率 :) Trick 6. 使用模板代码 idea默认的提供了许多模板代码,你可以使用 ...