【问题标题】:Segmentation fault error in function using 3D dynamic array使用 3D 动态数组的函数中的分段错误错误
【发布时间】:2017-08-06 13:22:12
【问题描述】:

我正在编写一个代码,其目的是操作来自 3D 数组的 1D 数组。显示代码将解释一切:

首先,我正在处理结构数组:

typedef struct range_in_memory {
      double E, R;
} RANGE;

我编写了这个函数,当在简单的调试实现中调用时,它就像一个魅力:

    RANGE *dq_Eloss_load_range_file (double Aion, double Zion, double Atar, double Ztar, int *n){

      char *filename;
      char errormsg[80], dummy;
      int N = 2;
      int i = 0;
      FILE *fp;
      RANGE *memrange;

      filename = (char*)malloc (50*sizeof (char));
      dq_Eloss_set_filename (filename, Aion, Zion, Atar, Ztar);  
      fp = dq_myfopen (filename, "r", errormsg);

      while ( !feof (fp) ){
        fscanf (fp, "%c", &dummy);

        if (dummy == '\n') {
          N++;

        }
      }

      rewind (fp);

      memrange = (RANGE*) calloc (N, sizeof (RANGE));

      while ( !feof (fp) ){
        fscanf (fp, "%lf\t%lf\n", &memrange[i].E, &memrange[i].R);
        i++;
      }
      *n = N;

    //   for (i=0; i<N; i++){
    //         printf ("\n%lf  %lf", memrange[i].E, memrange[i].R);
    //   }

      fclose (fp);

      return (memrange);
}

循环的注释至关重要,因此请牢记。 现在,谈到我的问题,我需要使用 3D 数组,例如:

RANGE ***memrangeTAR;

函数*dq_Eloss_load_range_file 将文件的内容加载到一个RANGE 类型的数组中。我想对几个文件执行此操作,这些文件根据两个参数AionZion 命名。在我看来,它应该是这样的:

(double) memrangeTAR [Aion][Zion][i].E
(double) memrangeTAR [Aion][Zion][i].R

这将是与 Aion 和 Zion 相关的文件中第 i 行中的值。

这是代码:

void dq_load_range_files (RANGE ***memrangeTAR){
  int NTAR;
  double *ZMAX;
  int Aion, Zion, AMAX = 250.;
  int i;



  printf ("\n   Allocating Memory for range data..."); fflush (stdout);
  ZMAX = (double*) malloc ((AMAX+1)*sizeof (double));
  memrangeTAR   = (RANGE***) malloc ((AMAX+1)*sizeof (RANGE**));


  for (Aion=1; Aion<=AMAX; Aion++){
    ZMAX[Aion] = ceil (dq_range_table_get_max_Zion (Aion)); 
    memrangeTAR  [Aion] = (RANGE**) malloc ((ZMAX[Aion]+1)*sizeof(RANGE*)); 
  }

  printf ("   ...ALLOCATED!                                  \n\n");


  printf ("\n   Loading range data...\n"); fflush (stdout);

  for (Aion=1; Aion <=AMAX; Aion++){

        for (Zion=1; Zion<=ZMAX[Aion]; Zion++){

      memrangeTAR  [Aion][Zion] = dq_Eloss_load_range_file ((double)Aion, (double)Zion, cor_sosau16.mass.Mtar,  cor_sosau16.charge.Ztar,  &NTAR); 

//   for (i=0; i<N; i++){
//         printf ("\n%lf  %lf", memrangeTAR[Aion][Zion][i].E, memrangeTAR[Aion][Zion][i].R);
//   }   

    }
  }

}

它可以编译(在 unix 机器上使用 gnu99 标准的 gcc)。除非我尝试访问 3D 数组,否则它会运行。如果我在第一个函数中取消注释打印周期,我可以得到我想要的:它在终端上打印当前文件的内容。如果我在第二个函数中取消注释 for 循环,它会给我分段错误。

我做错了什么?

【问题讨论】:

  • 首先请阅读Why is “while ( !feof (file) )” always wrong?。其次,请阅读Do I cast the result of malloc?。第三,为什么要为filename分配内存?最后,在哪里你遇到了崩溃?在哪条线上?请用例如标记它一条评论。如果您不知道,那么请学习如何使用调试器来捕捉运行中的崩溃。
  • 您的代码中没有 3D 数组。成为一名 3 星级 C 程序员并不是一种恭维。使用*** 几乎总是代码错误的信号。
  • 使用mytype (*X)[a][b] = malloc(sizeof(mytype[n][a][b])); 分配真实的3D。
  • 我阅读了这两篇文章并理解了,我将在这方面轻松改进我的代码。分配文件名是因为函数 dq_Eloss_set_filename 的需要。它可以做得更好,但与主要错误无关。但是,我将寻求一种改进它的方法。调用函数 dq_Eloss_load_range_file 后会出现错误。如果我打印或以任何方式使用变量 memrangeTAR[Aion][Zion][i].E 或 memrangeTAR[Aion][Zion][i].R跨度>

标签: c arrays struct segmentation-fault dynamic-allocation


【解决方案1】:

我以某种方式设法解决但不明白为什么它是一个解决方案。 通过定义一个

RANGE *tmp;

变量,调用常用函数为

tmp = dq_Eloss_load_range_file ((double)Aion, (double)Zion, cor_sosau16.mass.Mtar, cor_sosau16.charge.Ztar, &amp;NTAR);

然后分配想要的指针:

memrangeTAR[Aion][Zion] = tmp;

我现在可以以任何方式使用变量的内容,例如:

   for (i=0; i<N; i++){
        printf ("\n%lf  %lf", memrangeTAR[Aion][Zion][i].E, 
                              memrangeTAR[Aion][Zion][i].R);
   } 

这样没有遇到segmentation fault错误,让我觉得问题出在我传递指针给函数的方式上,但是还是不明白……

【讨论】:

    猜你喜欢
    • 2017-03-06
    • 2021-08-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-11
    • 1970-01-01
    • 2013-09-04
    相关资源
    最近更新 更多