我需要这个运行,所以我可以分析我实验室的一些数据。但是,当程序运行并输入“n”的值时,它只会崩溃。有关如何纠正此问题的任何提示?
谢谢,这是代码:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int main()
{
FILE *magfield;
FILE *means;
FILE *variances;
double *mean;
double *variance;
double field[12000];
double time[12000];
double sum=0, squares=0;
int i, j=0, k=0, l=0, n=0;
magfield=fopen("C:\\Users\\Owner\\Documents\\Homework\\ILab\\magneticfield.txt","r");
means=fopen("C:\\Users\\Owner\\Documents\\Homework\\ILab\\means.txt","w");
variances=fopen("C:\\Users\\Owner\\Documents\\Homework\\ILab\\variances.txt","w");
for (i=0;i<12000;i++)
{
fscanf(magfield,"%f %f", &time[i], &field[i]);
//printf("%f %f\n", time[i], field[i]);
}
printf("How many data points would you like to be analyzed at a time?\n");
scanf("%i", &n);
mean=(double*)calloc(n,sizeof(double));
variance=(double*)calloc(n,sizeof(double));
for (i=0;i<12000;i+=n)
{
for(j=i;j<n;j++)
{
sum+=field[j];
squares+=field[j]*field[j];
}
mean[k]=sum/n;
variance[k]=squares/n-(mean[k]*mean[k]);
fprintf(means,"%f\n", mean[k]);
fprintf(variances,"%f\n", variance[k]);
sum=0;
squares=0;
k++;
}
free(mean);
free(variance);
printf("Press enter to continue...\n");
getch();
return 0;
}
答案 0 :(得分:2)
我建议您{f}后#include <assert.h>
和assert(magfield != NULL); assert(means != NULL); assert(variances != NULL);
。此外,您应该assert(fscanf(...) == 2);
和assert(scanf(...) == 1);
。这些是调试辅助工具:如果有任何失败,您将知道这是因为丢失文件或意外输入。 assert(mean != NULL); assert(variance != NULL);
以确保成功分配。您可以使用哪个断言来确保k始终小于n?当k是均值或方差的无效指数时,如何确保不访问均值[k]或方差[k]?
this page告诉您%f
格式说明符处理的类型是什么? &time[i]
和&field[i]
的类型是什么?这些问题的答案应该是相同的,否则你将处理未定义的行为。
为什么你使用非标准conio.h中的非可移植getch,当你可以使用标准stdio.h中的可移植getchar用于同样的目的时?
答案 1 :(得分:1)
您的mean
和variance
数组大小错误。您将它们分配为大小为n
个元素,但随后您将拥有外部循环:
for (i = 0; i < 12000; i += n)
{
...
mean[k] = sum/n;
variance[k] = squares/n - (mean[k]*mean[k]);
...
k++;
}
循环体将执行12000/n
次,对于小于n
(110)的平方根的任何12000
,将导致超过n
次迭代因此,k
会变得足够大,以便在两个数组的末尾之外发生越界访问。
在一个完全不同的通知中,你的内循环似乎不正确。也许它应该是:
for (j = i; j < i+n; j++)
{
sum += field[j];
squares += field[j]*field[j];
}
(您还必须确保i+n
不会超过12000
)