關於Linux系統下錯誤“浮點數異常(核心已轉儲)”的分析


1.問題發現
  有這樣一段代碼:
  #include <stdio.h>
   int main()
   {
      int a, b, num1, num2, temp;
      printf("please input two numbers:\n");
      scanf("%d,%d", &num1, &num2);
      if(num1 > 0 && num2 > 0) (1)
      {
         a = num1;
         b = num2;
         temp = a%b;
      }
      while(b != 0) (2)
      {
         a = b;
         b = temp;
         temp = a%b;
      }
      printf("gong yue shu : %d\n", a);
      printf("gong bei shu : %d\n", num1*num2/a);
      return 0;
   }
  該代碼輸入任何數字的執行結果(如圖1)都是“浮點數異常(核心已轉儲)”,剛剛見到這個問題讓人感覺摸不着頭緒,程序根本沒有用到浮點數,怎么會報告浮點數異常;
  
  圖1.程序運行結果
  
2.問題分析
  
  下面我們通過Linux自帶調試工具Gdb來進行調試,觀察程序的運行狀況。在編譯的是個加上“-g”選項,方便利用Gdb調試。


  
  圖2.編譯和調試指令
  
  程序編譯沒有錯誤,下面使用Gdb工具調試;在不知道問題產生根源的情況下,先在(1)處設置斷點,全速運行;
  
  
  圖3.斷點之前運行情況
  從圖3可見,進入斷點前,程序運行正常;下面查看變量num1、num2的值。
  
  
  圖4.變量賦值情況
  
  由圖4可見,變量num1、num2的值正常讀入。下面將斷點設置在(2)處,全速運行。
  
  
  圖5.進入斷點2前程序運行情況
  
  由圖4可見,進入while循環之前,程序正常運行。查看變量a、b賦值情況發現此時變量a、b均按照程序預期賦值。
  
  
  圖6.變量a、b賦值情況
  
  下面開始單步運行。由圖7可見,第一次循環結束變量a的值為4,b的值
  
  
  圖7.第一次循環執行情況
  
為2,temp的值為0;繼續單步運行。從圖8可以看出,在第二次進入循環執行


  

  圖8.第二次循環執行情況

語句“temp = a%b;”的時候出現了錯誤。分析變量值發現此時變量a的值為2,b的值為0,對0求余是沒有意義的,語法不允許。到此,問題水落石出。
  現在,我們編寫測試代碼對問題產生原因進行驗證,代碼如下:
  
  #include <stdio.h>
  int main(int argc , char *argv[])
  {
     int a=5,b=0;
     printf("%d\n",a%b);
     return 0;
  }
  
  
  圖9.測試代碼運行情況
  
  由圖9可見,該錯誤系求余運算符右邊操作數為0值所致。如果把測試代碼的“a%b”改為“a/b”,運行結果仍然是浮點數例外。求余運算和除法運算不允許右邊的操作數為0值,我們在編寫程序的時候需小心謹慎,注意程序的邏輯,避免之中錯誤的發生。問題代碼系網上引用,其中輾轉相除法的邏輯錯誤,此處不加討論。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM