-5

我需要运行它,这样我就可以分析我实验室的一些数据。但是,当程序运行并且我输入“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;
}
4

2 回答 2

2

我建议在你#include <assert.h>assert(magfield != NULL); assert(means != NULL); assert(variances != NULL);fopens 之后。此外,您可能应该assert(fscanf(...) == 2);assert(scanf(...) == 1);。这些是调试辅助工具:如果出现任何故障,您就会知道这是因为缺少文件或意外输入。assert(mean != NULL); assert(variance != NULL);以确保成功分配。您可以提出哪个断言来确保 k 始终小于 n?当 k 是均值或方差的无效索引时,如何确保不访问均值 [k] 或方差 [k]?

这个页面告诉你%f格式说明符处理的类型是什么?&time[i]和的类型是&field[i]什么?这些问题的答案应该是相同的,否则您将处理未定义的行为。

你为什么要使用非标准 conio.h 中的非便携式 getch,而你可以只使用标准 stdio.h 中的便携式 getchar 来实现相同的目的?

于 2013-02-20T01:05:29.560 回答
1

你有错误的大小meanvariance数组。您将它们分配给 sizen元素,但随后您就有了外循环:

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

于 2013-02-20T08:47:54.707 回答