arrays - 打印数组后出现分段错误?
问题描述
我正在编写一个代码来获取用户的输入,并通过数组将其完全按照输入的方式打印出来。
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 行 x 10 列的字符数组,而b
一个整数数组,大小也是 10 行。n
是用户在创建数组之前输入的数字,指定数组中的字符串数量。输入看起来像这样:
5
Jimmy 90
Tony 80
Troy 67
Dona 78
Dylan 97
此时它会切断并打印正常工作的数组。但是,在完成打印名称后,终端会吐出大量数字和随机字符串,然后给我这个错误:
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.
我在网站上搜索过这个错误,但已经提出的问题与我的问题无关; 打印 分段错误核心转储后出现奇怪的分段错误 这些只是我见过的两个,它们不是我要寻找的答案。
我从进一步的搜索中看到,这可能是指针错误,或者是引用数组时代码中的大小差异。我将问题缩小到仅在打印完名称后才发生。所以我尝试更改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);
}
解决方案
你需要写:
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
它本身没有改变。
相反,您必须通过使用传递“地址”(或“指针” num
)int* n
。
你得到的垃圾是因为你根本不更新的num
inmain()
包含一些未定义的值(可能来自处理器堆栈,取决于你的平台和 C 编译器的实现)。
在您的情况下,这个垃圾/未定义值num
巧合地高于 4。这会导致您扫描的值被打印出来,再加上大量未定义的值,这些值在names[]
和scores[]
.
在 C 中,通常用 为指针添加前缀p
,因此您可能希望在pN
上面编写。
以上是为了让事情正常进行。但还有更多要说的:目前您的数组具有固定大小。如果您输入 20n
和/或输入非常长的名称,您的程序将以未定义的方式运行,因为您的数组太小。如果您想坚持使用固定大小的数组,您至少应该检查num
输入名称的值和长度。
推荐阅读
- android - 错误:无法从静态上下文引用非静态方法 unbind()
- python - 为 python2/3 返回对 super() 的兼容调用
- java - Android java 我想使用我的过滤数据列表?
- swift - 使用 NSBezierPath 绘制一个点
- python - (Python)格式化列表中的元素
- php - PHP & SQL Server,致命错误:未捕获错误:调用未定义函数 sqlsrv_connect()
- javascript - 在 Material-ui 上为 React.js 设置容器宽度
- css - Bulma - 瓷砖没有打破到下一行
- angularjs - 仅在 nginx 中限制 REST API 对 Angular 应用程序的访问
- sql - 显示零或一的查询表达式