簡體   English   中英

運行此代碼時為什么會出現分段錯誤?

[英]Why am I getting a segmentation fault when I run this code?

我正在學習使用switch語句以及使用rand()和srand()函數,但是當我嘗試運行從本書中獲得的代碼時,卻遇到了段錯誤。 是什么導致這種情況發生?

#include <stdio.h>

int main(void)
{

int iRandomNum = 0;
srand(time());

iRandomNum = (rand() % 4) + 1;

printf("\nFortune Cookie - Chapter 3\n");

  switch (iRandomNum) {

   case 1:
      printf("\nYou will meet a new friend today.\n");
      break;
   case 2:
      printf("\nYou will enjoy a long and happy life.\n");
      break;
   case 3:
      printf("\nOpportunity knocks softly. Can you hear it?\n");
      break;
   case 4:
     printf("\nYou'll be financially rewarded for your good deeds.\n");
      break;

  } //end switch

printf("\nLucky lotto numbers: ");
printf("%d ", (rand() % 49) + 1);
printf("%d ", (rand() % 49) + 1);
printf("%d ", (rand() % 49) + 1);
printf("%d ", (rand() % 49) + 1);
printf("%d ", (rand() % 49) + 1);
printf("%d\n", (rand() % 49) + 1);

} //end main function

這是因為time()需要一個參數,編譯器會告訴您是否打開了所有警告,例如使用gcc -Wall -Wextra ...

不包括time.h (意味着time()獲得默認原型)和不帶參數調用它的組合是您的特定問題。

使用higehr警告級別時發現的問題的完整列表是:

  • time() srand()rand()沒有原型,你需要#include兩個stdlib.htime.h
  • time()需要一個參數,例如srand (time (0))
  • 您應該返回從一些main (不是絕對必要的非常近的語言重復,但還是不錯的做法)。

以下更改可以正常工作:

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

int main (void) {
    int iRandomNum = 0;
    srand (time (0));

    iRandomNum = (rand() % 4) + 1;

    printf("\nFortune Cookie - Chapter 3\n");

    switch (iRandomNum) {
        case 1:
            printf("\nYou will meet a new friend today.\n");
            break;
        case 2:
            printf("\nYou will enjoy a long and happy life.\n");
            break;
        case 3:
            printf("\nOpportunity knocks softly. Can you hear it?\n");
            break;
        case 4:
            printf("\nYou'll be financially rewarded for your good deeds.\n");
            break;
    } //end switch

    printf("\nLucky lotto numbers: ");
    printf("%d ", (rand() % 49) + 1);
    printf("%d ", (rand() % 49) + 1);
    printf("%d ", (rand() % 49) + 1);
    printf("%d ", (rand() % 49) + 1);
    printf("%d ", (rand() % 49) + 1);
    printf("%d\n", (rand() % 49) + 1);

    return 0;
}

我使用gdb調試您的代碼,並且您的段錯誤發生在以下行:

srand(time());

您使用的time()錯誤。 您需要傳遞一個將保存結果時間的參數,但是NULL將導致該函數return時間:

srand(time(NULL));

另外,請確保始終main()函數return

這段代碼可以正常工作:

#include <stdlib.h>
#include <stdio.h>
#include <time.h>

int main(void)
{

int iRandomNum = 0;
srand(time(NULL));

iRandomNum = (rand() % 4) + 1;

printf("\nFortune Cookie - Chapter 3\n");

  switch (iRandomNum) {

   case 1:
      printf("\nYou will meet a new friend today.\n");
      break;
   case 2:
      printf("\nYou will enjoy a long and happy life.\n");
      break;
   case 3:
      printf("\nOpportunity knocks softly. Can you hear it?\n");
      break;
   case 4:
     printf("\nYou'll be financially rewarded for your good deeds.\n");
      break;

  } //end switch

printf("\nLucky lotto numbers: ");
printf("%d ", (rand() % 49) + 1);
printf("%d ", (rand() % 49) + 1);
printf("%d ", (rand() % 49) + 1);
printf("%d ", (rand() % 49) + 1);
printf("%d ", (rand() % 49) + 1);
printf("%d\n", (rand() % 49) + 1);

return 0;
} //end main function

以防萬一您對我的代碼調試方式感興趣,我使用調試符號和可能的每個編譯器警告對其進行了編譯:

gcc -g -Wall -Wextra test.c -o test

然后我啟動了gdb

gdb ./test
(gdb) run
Program received signal SIGSEGV, Segmentation fault.
0x00007ffff7ffba2c in time ()
(gdb) quit

您正在調用沒有參數的time() time()函數采用一個參數,並且不是可選的。

#include <time.h>

到源文件的頂部,然后將srand()調用更改為

srand(time(NULL));

編輯:

您還需要添加

#include <stdlib.h>

獲得srand()rand()的聲明。

編輯2:

您通常可以(貌似)不用調用函數而無需#include聲明聲明的標頭。

在C90中,如果調用沒有可見聲明的函數,則假定函數返回int並接受調用中給定的參數,則編譯器將為其隱式創建一個聲明。 實際上, srand()rand()都返回int結果,因此對它們的調用可以工作。 但是time()使用類型為time_t*的參數,並返回類型為time_t的結果; 如果您很“幸運”,則沒有聲明的呼叫可能會起作用,或者可能會炸掉您的臉。

1999 ISO C標准(C99)更改了規則,因此在沒有可見聲明的情況下調用函數會違反約束,需要編譯器進行診斷。

即使在C90模式下,如果您給正確的選項,也可以說服大多數編譯器警告未聲明的函數。

底線:如果要調用庫函數,請閱讀其文檔(手冊頁,或其他內容),並為標頭添加#include 如果您忘記這樣做, 也不要指望編譯器來提醒您。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM