运行此代码时,为什么会出现分段错误?

时间:2011-11-14 03:44:53

标签: c

我正在学习使用switch语句并使用rand()和srand()函数但是当我尝试运行这段代码时我得到了一个分段错误我从本书中得到了我正在学习C从。什么可能导致这种情况发生?

#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

3 个答案:

答案 0 :(得分:5)

这是因为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;
}

答案 1 :(得分:3)

我使用gdb来调试您的代码,并且您的段错误发生在此行:

srand(time());

您错误地使用了time()。您需要传递一个能够保存结果时间的参数,但NULL会使函数的时间为return

srand(time(NULL));

此外,请确保return功能始终 main()

此代码可以正常工作:

#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

答案 2 :(得分:2)

你在没有参数的情况下调用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。并且指望编译器在您忘记执行此操作时提醒您。