關於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可見,進入斷點前,程序運行正常;下面查看變量num一、num2的值。
  
  
  圖4.變量賦值狀況
  
  由圖4可見,變量num一、num2的值正常讀入。下面將斷點設置在(2)處,全速運行。
  
  
  圖5.進入斷點2前程序運行狀況
  
  由圖4可見,進入while循環以前,程序正常運行。查看變量a、b賦值狀況發現此時變量a、b均按照程序預期賦值。
  
  
  圖6.變量a、b賦值狀況
  
  下面開始單步運行。由圖7可見,第一次循環結束變量a的值爲4,b的值
  
  
  圖7.第一次循環執行狀況
  
爲2,temp的值爲0;繼續單步運行。從圖8能夠看出,在第二次進入循環執行測試


  

  圖8.第二次循環執行狀況spa

語句「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值,咱們在編寫程序的時候需當心謹慎,注意程序的邏輯,避免之中錯誤的發生。問題代碼系網上引用,其中展轉相除法的邏輯錯誤,此處不加討論。3d

相關文章
相關標籤/搜索