這些bug,你遇到過嗎,持續更新中……

記錄一些C語言易出的bug,有些是自己編程中遇到的,有些是在其他地方看到的:

1、釋放動態內存時遇到“user breakpoint called from code at 0x********”

這個bug多在調用free函數來釋放malloc的內存時出現,前先曾多次遇到,但一直未找出問題原因。

在網上查了一下,有些寫得挺複雜,涉及到了操作系統推維護的內容,現在還不有接觸到這一塊,所以沒有細看。其他有說到重複釋放動態內存,修改動態內存指針或者破壞了系統的動態內存結束標誌都會導致這個bug。後來查看自己的代碼,發現重複釋放的問題倒是沒有,卻在操作內存時有一處頻繁操作超出動態申請內存之外的單元,故導致這個問題的出現。

問題總結:在動態內存釋放時出現,多由於動態內存使用不當
1、重複釋放動態內存,調用free後應立即將指針賦NULL,最好寫個宏將free和指針賦NULL包含進去,以免遺漏;
2、讀寫操作超出了動態申請內存邊界(讀應該不會發生問題,但也要避免,除非你真正明白自己在幹什麼)

2、C中的字符串異常

嚴格地說,C中是沒有字符串變量的,一般採用字符數組或字符指針的方式才實現字符串的操作,二者在使用中有諸多類似,但並不是完全等價的,注意下面兩句的區別:
 

  1. char a[] = "Hello world";//存放在棧中,可以修改a數據組的任意值  
  2. char *s = "Hello world";//指針s存放在棧中,字符串常量在代碼段,不可修改  

給s[i]賦值將導致錯誤

3、條件判斷時一定要學會利用短路特性來防止異常,如
 

  1. while(j >=0 && a[j] >0) j--;  
  2. if(d != 0 && n/d == 0)  
  3. if(p == NULL || *p == '\0')/*no string*/ 

例中3種情況漏掉前一個條件或將兩個判斷條件調換了次序都會導致內存溢出。

4、關於混亂的類型擴展問題

因爲不確定編譯器採用哪種保護規則(無符號保護或是值保護),應儘量避免在同一個表達式內混用有符號和無符號的變量。任何時候,總可以用顯式的類型轉換來明確無誤地表達所希望的轉換的地方或方式。

5、類型轉換被當成左值

在C語言中,類型轉換操作只能生成一個右值,不能被賦值或進行自增(減)運算。

  1. char *p;  
  2. ((int *)p)++; 

不能完成預想中的將p增加一個int的長度,而應該如下:
p= (char *)((int *)p + 1);

或p += sizeof(int);

6、變長參數函數調用中,會進行默認類型轉換嗎?

下面這段代碼的輸出是什麼?

  1. #include <stdio.h>  
  2.  
  3. int main()  
  4. {  
  5.     __int64 n;  
  6.     int b;  
  7.  
  8.     n = 1;  
  9.     b = 2;  
  10.     printf("%d,%d\n",n,b);  
  11.     return 0;  

和預料不同的是,它輸出:1,0

這是因爲在可變參數函數調用中,一般編譯器是不進行默認類型轉換的,當函數根據格式字符串從棧中提取參數時就會由於變量長度不一致而產生異常的輸出。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章