2017-03-15 2 views
-1

私は、3D配列から来る1D配列を操作するコードを作成しています。コードを表示すると、すべてを説明します:すべての3Dダイナミックアレイを使用した関数のセグメンテーションフォールトエラー

まず、私は、構造体の配列で働いている:

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); 
} 

コメントされたサイクルは非常に重要なので、心に留めておいてください。

RANGE ***memrangeTAR; 

機能​​はRANGE型の配列int型ファイルの内容をロードします。 は今、私の問題に来て、私のような3次元の配列を使用する必要があります。私はこれを2つのパラメータAionZionに基づいて命名されたいくつかのファイルに対して行いたいと思います。アイオンとシオンに関連するファイル内のi番目の行の値であったであろう

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

:私の心の中で、それはのようなものだったでしょう。

これはコードである:

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); 
// } 

    } 
    } 

} 

これは(gnu99標準を使用してUNIXマシン上のGCC)コンパイル。 3Dアレイにアクセスしようとしない限り動作します。最初の関数で印刷サイクルをコメント解除すると、私は必要なものを得ることができます。これは、現在のファイルの内容を端末に出力します。 2番目の関数のforサイクルをコメント解除すると、セグメント化エラーが発生します。

私は間違っていますか?

+0

まずお読みください。 [なぜwhile(!feof(file))が常に間違っているのですか?](http://stackoverflow.com/questions/5431941/why-is-while-feof-file-always-wrong)次に、[私はmallocの結果をキャストしていますか?](http://stackoverflow.com/questions/605845/do-i-cast-the-result-of-malloc)をお読みください。第三に、なぜあなたは 'filename'のためにメモリを割り当てますか?最後に*どこでクラッシュするのですか?どの行?たとえば、次のようにマークしてください。コメント。また、わからない場合は、デバッガを使用してクラッシュを実行する方法を学習してください。 –

+3

コードに3D配列がありません。そして3つ星のCプログラマであることは賛辞ではありません。 '***'を使うことは、ほとんど常に悪いコードのシグナルです。 – Olaf

+0

実際の3Dを 'mytype(* X)[a] [b] = malloc(sizeof(mytype [n] [a] [b]));'として割り当てます。 –

答えて

0

私は何とか解決することができましたが、それが解決策である理由を理解していません。私はのコンテンツを使用することができます

memrangeTAR[Aion][Zion] = tmp;

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

いつものように関数を呼び出し、

RANGE *tmp;

変数を定義して、割り当てることにより は、ポインタを望んでいましたどのような変数でも、今のように:01私はまだ理解していない問題は、私は関数へのポインタを渡した方法だったと思いますが、作る何セグメンテーションフォールトエラーが発生していない。このように

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