一次陣列越界的bug經歷

2022-01-24 13:10:09 字數 1943 閱讀 9848

陣列和指標都是c裡面的好東西,但是一旦使用不當,真的會讓人抓狂。

下面是寫程式時遇到的一次陣列越界的經歷,感覺對以後寫程式有點啟發,所以記錄下來。

我想用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)

思路就是把小數點後一位後面的殘餘資料用空格重新整理。但是實驗現象是在顯示完第一行資料之後,本來應該在第二行顯示第二個資料,但是他 在第一行資料的後面又顯示了第二行的資料!!也就是說第二行資料顯示了兩次。

為什麼會顯示兩次呢?我程式中就寫了一次啊、、、

既然是顯示的問題,那就先看看這個顯示函式!

/*

----------------------------------

**函式名稱:oled_show_string

**功能描述:游標處顯示字串,字串可以用陣列表示,unsigned char string_2 = ;

**引數說明:x,y為座標

**日期:2018.1.24

-----------------------------------

*/void oled_show_string(u8 x, u8 y, u8 *chr)

//自動換行寫

j++;}}

原來這個函式會在陣列結束之前,顯示陣列的全部內容。因為陣列的最後乙個結尾標誌是'\0』那麼,上面第一行一直在顯示,說明他可能沒有遇到陣列結束識別符號。檢視陣列定義的大小:

unsigned char weight_string[7] = ;

unsigned

char price_string[3] = ;

原來 weight_string 陣列的最後乙個結束標誌被我賦值成了空格。那麼他就會一直讀取儲存在這個陣列後面的記憶體資料,並且給顯示出來。也就是所謂的「陣列越界」。幸好我們只是讀取顯示,並沒有改寫這個資料!既然他顯示的是第二行的資料,說明第二行的資料就是儲存在在這個陣列後面的記憶體中。

檢視編譯器生成的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,機房機架上的監控 伺服器 交換機,除錯完...