[英]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.h
和time.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.