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