我的代码应该打印到为每个学生输入的最高分,但是对于每个学生,它会重新打印所有学生的最高分。
任何人都可以解释原因吗?错误是什么......即使在纸上工作,我也看不到它。
//Take integer marks (0-100) of 3 tests of 4 students and print the highest score of respective student
#include<stdio.h>
int main (void)
{
int i=0, j=0, a=0, b=0;
int
arr[a][b],
max[i];
printf("Enter the number of students, and number of tests score per student: \n\n");
scanf("%d", &a);
scanf("%d", &b);
//int arr[][] = arr[a][b];
for(i=0; i<a; i++)
{
printf("Enter the scores for student %d \n", (i+1));
for(j=0; j<b; j++)
{
scanf("%d", &arr[i][j]);
}
}
for(i=0; i<a; i++)
{
max [i] = 0;
for(j=0; j<b; j++)
{
if(arr[i][j]>max[i])
{
max[i] = arr[i][j];
}
}
}
for(i=0; i<a; i++)
{
printf("The highest score for student %d was:\t %d\n\n", (i+1), max[i]);
}
}
答案 0 :(得分:2)
编译代码不会产生任何警告,做得很好,但使用-fsanitize=address
运行它会立即显示问题。
$ make
cc -fsanitize=address -Wall -Wshadow -Wwrite-strings -Wextra -Wconversion -std=c99 -pedantic -g `pkg-config --cflags glib-2.0` -c -o test.o test.c
cc `pkg-config --libs glib-2.0` -lssl -lcrypto -fsanitize=address test.o -o test
$ ./test
Enter the number of students, and number of tests score per student:
3
3
Enter the scores for student 1
5
=================================================================
==80655==ERROR: AddressSanitizer: dynamic-stack-buffer-overflow on address 0x7ffeed7491e0 at pc 0x0001028420c3 bp 0x7ffeed749060 sp 0x7ffeed748820
WRITE of size 4 at 0x7ffeed7491e0 thread T0
10 #0 0x1028420c2 in scanf_common(void*, int, bool, char const*, __va_list_tag*) (libclang_rt.asan_osx_dynamic.dylib+0x1a0c2)
#1 0x10284235e in wrap_scanf (libclang_rt.asan_osx_dynamic.dylib+0x1a35e)
#2 0x1024b76e0 in main (/Users/schwern/tmp/./test+0x1000016e0)
#3 0x7fff5d504014 in start (/usr/lib/system/libdyld.dylib+0x1014)
问题出在这里。
int i=0, j=0, a=0, b=0;
int arr[a][b], max[i];
arr
初始化为arr[0][0]
,永不延期。当您尝试使用arr[i][j]
写入scanf("%d", &arr[i][j])
时,将不会分配内存。相反,该程序将覆盖其他一些内存,并会发生奇怪的事情。相反,{<1}}必须在获取大小后初始化。与arr
类似的问题。
这类错误通常是在函数开始时执行所有变量声明和初始化的罪魁祸首。这是一种你会看到很多的风格,但除非你使用非常古老的编译器,否则不再需要它。
相反,在上下文中声明您的变量。然后它显而易见的是他们的目标。并且只在必要时初始化它们,然后你可以得到未初始化的值&#34;来自编译器的警告。
要解决此问题,我们可以为max
和arr
分配内存,但像max
这样的allocating a 2D array并不简单。
相反,我们可以观察到所有外部循环遍历相同的事情:测试的数量。无需存储所有学生的考试成绩,然后计算最高成绩。我们可以在一个循环中完成每个学生。不需要在循环之间存储数据的数组。
arr