陣列和指標都是c裡面的好東西,但是一旦使用不當,真的會讓人抓狂。
下面是寫程式時遇到的一次陣列越界的經歷,感覺對以後寫程式有點啟發,所以記錄下來。
我想用oled動態顯示一組浮點數,而且浮點數的長度是不定的。
於是有了下面這樣的程式:
sprintf((char *)weight_string,"這段程式在定時器中斷函式中呼叫。weight 和 price 就是我想顯示的浮點數。%.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);
先格式化為字串,然後顯示。oled_show_string() 的前兩個引數是字元的起始顯示座標。
clear_left_num 函式如下:
void clear_left_num(unsigned char *num_string)思路就是把小數點後一位後面的殘餘資料用空格重新整理。但是實驗現象是在顯示完第一行資料之後,本來應該在第二行顯示第二個資料,但是他 在第一行資料的後面又顯示了第二行的資料!!也就是說第二行資料顯示了兩次。
為什麼會顯示兩次呢?我程式中就寫了一次啊、、、
既然是顯示的問題,那就先看看這個顯示函式!
/*原來這個函式會在陣列結束之前,顯示陣列的全部內容。因為陣列的最後乙個結尾標誌是'\0』那麼,上面第一行一直在顯示,說明他可能沒有遇到陣列結束識別符號。檢視陣列定義的大小:----------------------------------
**函式名稱:oled_show_string
**功能描述:游標處顯示字串,字串可以用陣列表示,unsigned char string_2 = ;
**引數說明:x,y為座標
**日期:2018.1.24
-----------------------------------
*/void oled_show_string(u8 x, u8 y, u8 *chr)
//自動換行寫
j++;}}
unsigned char weight_string[7] = ;原來 weight_string 陣列的最後乙個結束標誌被我賦值成了空格。那麼他就會一直讀取儲存在這個陣列後面的記憶體資料,並且給顯示出來。也就是所謂的「陣列越界」。幸好我們只是讀取顯示,並沒有改寫這個資料!既然他顯示的是第二行的資料,說明第二行的資料就是儲存在在這個陣列後面的記憶體中。unsigned
char price_string[3] = ;
檢視編譯器生成的map檔案:
第乙個陣列讀取越界之後,讀到了第二個陣列。
到此,問題解決。
一定要看到程式的內在聯絡。分析記憶體雖然困難,但是卻是找到煩人bug 的捷徑。
記一次資料越界的事
最近在作乙個基於聯盛德的 w600晶元進行ayla雲移植時,用到了作業系統的tick獲取,獲取函式如下 u32 clock ms void else return ms 測試 現了奇怪的問題,系統走著走著就不發心跳包了,最後跟蹤後發現是上面這個函式返回的值突然變零 我們預想上面的返回值會一直增加,至...
記錄一次陣列的操作
運算元組的常見的方法有foreach map filter,其中map和filter方法的返回值都是陣列,foreach的返回值是undefined,可以理解為沒有返回值。由於原生的陣列物件中,沒有concatall方法,所以打算自己實現乙個。concatall方法要做的事情很簡單,就是把乙個二維陣...
一次佈線的經歷
一次佈線的經歷 由於公司要重sz搬遷到sd,sd區需要裝修整改,重新佈線。專案開始2012年10月份入職就開始入手 左邊是工廠區 辦公區 凹字形結構 共4層樓,是拼接房大部分是翻新,只有 內凹部分那裡新建 www.2cto.com 專案結束標誌以機房的ups,機房機架上的監控 伺服器 交換機,除錯完...