编译良好的C程序中的分段错误

编译良好的C程序中的分段错误,c,C,我正在解决USACO的一个问题。在这个问题中,我必须取两个字符串作为输入,然后计算模47的数值。如果值相同,则要打印GO,否则必须打印STAY。初始数值将通过字母的数值乘积(A为1,Z为26)进行计算,然后使用模计算最终数值 我的程序正在编译,没有任何错误,并且在我的计算机上运行良好。但是,分级计算机显示分段错误作为执行错误。程序和输出如下所示:- 节目:- #include<stdio.h> #include<string.h> main() { int cal

我正在解决USACO的一个问题。在这个问题中,我必须取两个字符串作为输入,然后计算模47的数值。如果值相同,则要打印GO,否则必须打印STAY。初始数值将通过字母的数值乘积(A为1,Z为26)进行计算,然后使用模计算最终数值

我的程序正在编译,没有任何错误,并且在我的计算机上运行良好。但是,分级计算机显示分段错误作为执行错误。程序和输出如下所示:-

节目:-

#include<stdio.h>
#include<string.h>
main()
{
    int cal(char *ptr);
    char *comet,*group;
    int a,b;
    scanf("%s",comet);
    a=cal(comet);
    scanf("%s",group);
    b=cal(group);
    if(a==b)
        printf("GO");
    else
        printf("STAY");
    return 0;
}
int cal(char *ptr)
{
    int i=0,c,prod=1,mod;
    while(ptr[i]!='\0')
        {
            if(ptr[i]>='A'&&ptr[i]<='Z')
            {
                c=ptr[i]-'@';
                prod=prod*c;
                i++;
            }
        }
    mod=prod%47;
    return mod;
}
#包括
#包括
main()
{
int-cal(字符*ptr);
char*comet,*组;
INTA,b;
scanf(“%s”,彗星);
a=cal(彗星);
scanf(“%s”,组);
b=cal(组);
如果(a==b)
printf(“GO”);
其他的
printf(“停留”);
返回0;
}
内部校准(字符*ptr)
{
int i=0,c,prod=1,mod;
而(ptr[i]!='\0')
{
如果(ptr[i]>='A'&&ptr[i]
comet
指针未初始化。您需要分配内存并使
comet
指向此分配内存,否则
scanf
将在随机位置写入字节,这可能会使系统崩溃


comet
指针未初始化。您需要分配内存并使
comet
指向此分配的内存,否则
scanf
将在随机位置写入字节,这可能会使您的系统崩溃。

您从不为
comet
组分配空间。用于为这些指针,这样你就可以在它们指向的地方存储一些东西

#define MAX_STRING_LENGTH 256

...

char *comet, *group;
int a, b;

comet = NULL;
comet = malloc(MAX_STRING_LENGTH);
if (!comet) {
   fprintf(stderr, "ERROR: Could not allocate memory to comet\n");
   return EXIT_FAILURE;
}
scanf("%s",comet);

/* repeat for other pointers, as needed */

/* ... */

/* free up allocated memory at the end of the program to help prevent leaks */

free(comet);
comet = NULL;

您从不为
comet
group
分配空间。用于为这些指针留出内存,以便您可以实际存储它们所指向的内容

#define MAX_STRING_LENGTH 256

...

char *comet, *group;
int a, b;

comet = NULL;
comet = malloc(MAX_STRING_LENGTH);
if (!comet) {
   fprintf(stderr, "ERROR: Could not allocate memory to comet\n");
   return EXIT_FAILURE;
}
scanf("%s",comet);

/* repeat for other pointers, as needed */

/* ... */

/* free up allocated memory at the end of the program to help prevent leaks */

free(comet);
comet = NULL;

comet和group都是未初始化的指针,没有为存储输入字符串分配任何内存

你的程序至少应该这样做。根据需要增加最大字符串大小

#define MAX_STRING_SIZE 100
char comet[MAX_STRING_SIZE];
char group[MAX_STRING_SIZE];

使用scanf仍然存在缓冲区溢出的风险。您可以查看post以找到一些可能的方法来避免缓冲区溢出。

comet和group都是未初始化的指针,没有分配任何内存来存储输入字符串

你的程序至少应该这样做。根据需要增加最大字符串大小

#define MAX_STRING_SIZE 100
char comet[MAX_STRING_SIZE];
char group[MAX_STRING_SIZE];

scanf仍然存在缓冲区溢出的风险。您可以查看post以找到一些可能的方法来避免缓冲区溢出。

您的
,而
非常可疑:
i
只有在
ptr[i]时才会增加
是大写字母。如果不是,该怎么办?如果你有铁一般的保证,保证只显示大写字母,你可以写:

prod = 1;
while(*ptr) {
  prod *= *ptr - 'A' + 1;
  ptr++;
}
(你的
ptr[i]-“@”
让我挠头,直到我破解了ascii(7)。我相信我的版本更清晰,任何有一半能力的编译器都会给出相同的代码。) 或者,更习惯地说:

int cal(char *ptr)
{
    int prod = 1;

    while(*ptr)
       prod *= *ptr++ - 'A' + 1;
    return prod % 47;
}
只需注意产品不会溢出,可能需要对每个字符进行模数计算:

int cal(char *ptr)
{
    int prod = 1;

    while(*ptr) {
       prod *= *ptr++ - 'A' + 1;
       prod %= 47;
    }
    return prod;
}

你的
while
非常可疑:
i
只有在
ptr[i]
是大写字母时才会增加。如果不是,该怎么办?如果你有铁一般的保证,保证只显示大写字母,你可以写:

prod = 1;
while(*ptr) {
  prod *= *ptr - 'A' + 1;
  ptr++;
}
(你的
ptr[i]-“@”
让我挠头,直到我破解了ascii(7)。我相信我的版本更清晰,任何有一半能力的编译器都会给出相同的代码。) 或者,更习惯地说:

int cal(char *ptr)
{
    int prod = 1;

    while(*ptr)
       prod *= *ptr++ - 'A' + 1;
    return prod % 47;
}
只需注意产品不会溢出,可能需要对每个字符进行模数计算:

int cal(char *ptr)
{
    int prod = 1;

    while(*ptr) {
       prod *= *ptr++ - 'A' + 1;
       prod %= 47;
    }
    return prod;
}
“在我的计算机上运行良好”这在您的情况下是不可能的,因为您没有使用任何特定于编译器的代码(如getch for turbo c)

您没有为存储字符串分配内存。指针comet和group不指向任何内容。scanf需要一个地址来写入输入,但指针不包含地址,这就是您遇到分段错误的原因。 可以使用malloc(或calloc)分配内存,也可以定义字符数组

更正后的代码为

#include<stdio.h>
#include<string.h>
#define MAXLENGTH 100
int main()
{
    int cal(char *ptr);
    char comet[MAXLENGTH],group[MAXLENGTH];
    int a,b;
    scanf("%s",comet);
    a=cal(comet);
    scanf("%s",group);
    b=cal(group);
    if(a==b)
        printf("GO");
    else
        printf("STAY");
    return 0;
}
int cal(char *ptr)
{
    int i=0,c,prod=1,mod;
    while(ptr[i]!='\0')
    {
        if(ptr[i]>='A'&&ptr[i]<='Z')
        {
            c=ptr[i]-'@';
            prod=prod*c;
            i++;
        }
    }
    mod=prod%47;
    return mod;
}
#包括
#包括
#定义MAXLENGTH 100
int main()
{
int-cal(字符*ptr);
字符彗星[MAXLENGTH],组[MAXLENGTH];
INTA,b;
scanf(“%s”,彗星);
a=cal(彗星);
scanf(“%s”,组);
b=cal(组);
如果(a==b)
printf(“GO”);
其他的
printf(“停留”);
返回0;
}
内部校准(字符*ptr)
{
int i=0,c,prod=1,mod;
而(ptr[i]!='\0')
{
如果(ptr[i]>='A'&&ptr[i]“在我的计算机上运行良好”,这在您的情况下是不可能的,因为您没有使用任何特定于编译器的代码(如getch for turbo c)

您没有为存储字符串分配内存。指针comet和group不指向任何内容。scanf需要一个地址来写入输入,但指针不包含地址,这就是您遇到分段错误的原因。 可以使用malloc(或calloc)分配内存,也可以定义字符数组

更正后的代码为

#include<stdio.h>
#include<string.h>
#define MAXLENGTH 100
int main()
{
    int cal(char *ptr);
    char comet[MAXLENGTH],group[MAXLENGTH];
    int a,b;
    scanf("%s",comet);
    a=cal(comet);
    scanf("%s",group);
    b=cal(group);
    if(a==b)
        printf("GO");
    else
        printf("STAY");
    return 0;
}
int cal(char *ptr)
{
    int i=0,c,prod=1,mod;
    while(ptr[i]!='\0')
    {
        if(ptr[i]>='A'&&ptr[i]<='Z')
        {
            c=ptr[i]-'@';
            prod=prod*c;
            i++;
        }
    }
    mod=prod%47;
    return mod;
}
#包括
#包括
#定义MAXLENGTH 100
int main()
{
int-cal(字符*ptr);
字符彗星[MAXLENGTH],组[MAXLENGTH];
INTA,b;
scanf(“%s”,彗星);
a=cal(彗星);
scanf(“%s”,组);
b=cal(组);
如果(a==b)
printf(“GO”);
其他的
printf(“停留”);
返回0;
}
内部校准(字符*ptr)
{
int i=0,c,prod=1,mod;
而(ptr[i]!='\0')
{

如果(ptr[i]>='A'&&ptr[i]在为变量赋值之前,您不能使用该变量的值。在为该变量赋值之前,您不能使用该变量的值。您想检查
malloc()之后该值是否仍然为
NULL
因为您可能无法获得所需的空间。诚然,这是一个微不足道的示例,但是