打印数组后出现分段错误?
Segmentation Fault after printing an array?
我正在编写一个代码来获取用户的输入,并通过数组将输入的内容准确地打印出来。
void getArrays(char a[10][10], int b[10], int n ){
printf("Enter number of students and then those students names and scores separated by a space.\n");
scanf("%d", &n);
int i = 0;
while(i < n){
scanf("%s%d", a[i],&b[i]);
i++;
}
}
void printArrays(char a[10][10], int b[10], int n ){
int j;
for(j=0; j<n-1; j++){
printf("%s %d\n", a[j],b[j] );
}
}
在这种情况下,a
是一个 10 行 10 列的字符数组,而 b
是一个整数数组,大小也是 10 行。 n
是用户在创建数组之前输入的数字,指定数组中的字符串数量。
输入看起来像这样:
5
Jimmy 90
Tony 80
Troy 67
Dona 78
Dylan 97
此时它中断,并打印数组,它工作正常。然而,在完成名称打印后,终端在给我这个错误之前吐出大量数字和 运行dom 字符串:
Segmentation Fault (core dumped)
我运行它通过gbd调试器,得到了以下信息:
Program received signal SIGSEGV, Segmentation fault.
__strlen_avx2 () at ../sysdeps/x86_64/multiarch/strlen-avx2.S:65
65 ../sysdeps/x86_64/multiarch/strlen-avx2.S: No such file or directory.
我在网站上搜索了这个错误,但是已经提出的问题与我的问题无关;
Weird Segmentation Fault after printing
Segmentation fault core dump
这些只是我见过的其中两个,它们不是我要找的答案。
我进一步搜索发现这可能是指针错误,或者引用数组时代码中的大小不一致。我将问题缩小到仅在打印完名称后才会发生。所以我尝试将 for(j=0; j<n; j++)
更改为 for(j=0; j<n-1; j++)
,但它又一次给了我同样的问题。
我认为 for 循环可能正在读取超过我想要的元素数量,即 - 而不是停在 3,(如果 n
= 3),并且它没有其他要打印的东西它给我分段错误?
在这种情况下,我是否需要使用带有 n
的指针,例如 &n
,或者问题是否与我的数组大小有关?
调用这些函数的代码如下:
int main(){
char names[10][15]; // can handle up to 10 students
int scores[10];
int num;
int average;
getScores(names, scores, num);
printScores(names, scores, num);
}
考虑到函数getArrays
正在局部修改变量n(因为函数定义是这样的:
void getArrays(char a[10][10], int b[10], int n )
应该是这样的:
void getArrays(char a[10][10], int b[10], int* n )
所以您提供给 printArrays
的 n 值可能未初始化。
另一方面,printArrays
中的循环看起来定义错误:
for(j=0; j<n-1; j++)
应该是
for(j=0; j<n; j++)
你需要写:
int num;
getScores(... &num);
printScores(... num);
并且:
getScores(... int* n)
{
scanf("%d", n)
...
while (i < *n) { // Dereference the pointer `n` to get the value again.
使用 getScores(... int n)
你只需传递 num
的当前值,而 getScores()
只会修改它的 num
的本地副本(即 n
); num
本身并没有改变。
相反,您必须使用 int* n
传递“地址”(或“指向”)num
。
你得到的垃圾是因为你根本不更新的 main()
中的 num
包含一些未定义的值(可能来自处理器堆栈,具体取决于你的平台和 C 编译器)。
在您的情况下,num
的 garbage/undefined 值巧合地高于 4。这会导致打印您扫描的值加上许多再次未定义的值,这些值在 names[]
和 scores[]
.
在 C 中,通常在指针前加上 p
,因此您可能希望在上面写 pN
。
以上是为了让事情正常进行。但还有更多要说的:目前您的数组具有固定大小。如果您为 n
输入 20 and/or 输入非常长的名称,您的程序将以未定义的方式运行,因为您的数组太小了。如果你想坚持使用固定大小的数组,你至少应该检查 num
的值和输入名称的长度。
我正在编写一个代码来获取用户的输入,并通过数组将输入的内容准确地打印出来。
void getArrays(char a[10][10], int b[10], int n ){
printf("Enter number of students and then those students names and scores separated by a space.\n");
scanf("%d", &n);
int i = 0;
while(i < n){
scanf("%s%d", a[i],&b[i]);
i++;
}
}
void printArrays(char a[10][10], int b[10], int n ){
int j;
for(j=0; j<n-1; j++){
printf("%s %d\n", a[j],b[j] );
}
}
在这种情况下,a
是一个 10 行 10 列的字符数组,而 b
是一个整数数组,大小也是 10 行。 n
是用户在创建数组之前输入的数字,指定数组中的字符串数量。
输入看起来像这样:
5
Jimmy 90
Tony 80
Troy 67
Dona 78
Dylan 97
此时它中断,并打印数组,它工作正常。然而,在完成名称打印后,终端在给我这个错误之前吐出大量数字和 运行dom 字符串:
Segmentation Fault (core dumped)
我运行它通过gbd调试器,得到了以下信息:
Program received signal SIGSEGV, Segmentation fault.
__strlen_avx2 () at ../sysdeps/x86_64/multiarch/strlen-avx2.S:65
65 ../sysdeps/x86_64/multiarch/strlen-avx2.S: No such file or directory.
我在网站上搜索了这个错误,但是已经提出的问题与我的问题无关; Weird Segmentation Fault after printing Segmentation fault core dump 这些只是我见过的其中两个,它们不是我要找的答案。
我进一步搜索发现这可能是指针错误,或者引用数组时代码中的大小不一致。我将问题缩小到仅在打印完名称后才会发生。所以我尝试将 for(j=0; j<n; j++)
更改为 for(j=0; j<n-1; j++)
,但它又一次给了我同样的问题。
我认为 for 循环可能正在读取超过我想要的元素数量,即 - 而不是停在 3,(如果 n
= 3),并且它没有其他要打印的东西它给我分段错误?
在这种情况下,我是否需要使用带有 n
的指针,例如 &n
,或者问题是否与我的数组大小有关?
调用这些函数的代码如下:
int main(){
char names[10][15]; // can handle up to 10 students
int scores[10];
int num;
int average;
getScores(names, scores, num);
printScores(names, scores, num);
}
考虑到函数getArrays
正在局部修改变量n(因为函数定义是这样的:
void getArrays(char a[10][10], int b[10], int n )
应该是这样的:
void getArrays(char a[10][10], int b[10], int* n )
所以您提供给 printArrays
的 n 值可能未初始化。
另一方面,printArrays
中的循环看起来定义错误:
for(j=0; j<n-1; j++)
应该是
for(j=0; j<n; j++)
你需要写:
int num;
getScores(... &num);
printScores(... num);
并且:
getScores(... int* n)
{
scanf("%d", n)
...
while (i < *n) { // Dereference the pointer `n` to get the value again.
使用 getScores(... int n)
你只需传递 num
的当前值,而 getScores()
只会修改它的 num
的本地副本(即 n
); num
本身并没有改变。
相反,您必须使用 int* n
传递“地址”(或“指向”)num
。
你得到的垃圾是因为你根本不更新的 main()
中的 num
包含一些未定义的值(可能来自处理器堆栈,具体取决于你的平台和 C 编译器)。
在您的情况下,num
的 garbage/undefined 值巧合地高于 4。这会导致打印您扫描的值加上许多再次未定义的值,这些值在 names[]
和 scores[]
.
在 C 中,通常在指针前加上 p
,因此您可能希望在上面写 pN
。
以上是为了让事情正常进行。但还有更多要说的:目前您的数组具有固定大小。如果您为 n
输入 20 and/or 输入非常长的名称,您的程序将以未定义的方式运行,因为您的数组太小了。如果你想坚持使用固定大小的数组,你至少应该检查 num
的值和输入名称的长度。