2017-03-15 68 views
-1

我正在處理一個代碼,其目的是操縱來自3D數組的一維數組。顯示的代碼會解釋一切:使用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); 
} 

評論的週期是至關重要的,所以記住它。 現在,來參加我的問題,我需要使用3D陣列,如:

RANGE ***memrangeTAR; 

功能​​加載文件的內容INT RANGE類型的數組。我想爲幾個文件執行此操作,這些文件根據兩個參數AionZion命名。在我的腦海裏它會一直是這樣的:

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

這將在與永恆之塔錫安文件中的第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); 
// } 

    } 
    } 

} 

它編譯器(gcc UNIX機器上使用gnu99標準)。它運行除非我嘗試訪問3D數組。如果我在第一個函數中取消註釋打印週期,我可以得到我想要的:它在終端上打印當前文件的內容。如果我對第二個函數中的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數組。作爲一名三星級C程序員並不是一種恭維。使用'***'幾乎總是錯誤代碼的信號。 – Olaf

+0

做一個真實的3D的分配,如'mytype(* X)[a] [b] = malloc(sizeof(mytype [n] [a] [b]));'。 –

回答

0

我以某種方式設法解決但不明白爲什麼這是一個解決方案。 通過定義

RANGE *tmp;

變量,調用通常的功能作爲

tmp = dq_Eloss_load_range_file ((double)Aion, (double)Zion, cor_sosau16.mass.Mtar, cor_sosau16.charge.Ztar, &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); 
    } 

這樣沒有遇到分段錯誤,讓我覺得現在的問題是我經過函數指針的方式,但還是不明白......