2013-03-21 149 views
0

我似乎無法在下面的代碼中找到段錯誤的原因。在從evaluate()跳回到main()後,代碼在註釋行中崩潰。我用gdb看了這段代碼,看起來在評估函數中一切正常 - 輸出被正確填充,但是在我返回到main之後,內存中的任何內容都不能被訪問。 gdb中的「p j」返回內存不可訪問錯誤,就像試圖打印任何其他變量一樣。我檢查了堆棧可能是否有很多值,但增加堆棧大小並沒有幫助。C中的分段錯誤,似乎無法找到原因

瘋狂的事情是我可以解決這個錯誤,但我不知道它爲什麼會改變任何東西。如果我在evaluate()中的任何地方添加一個int聲明(例如int iAmNotUsedEver;),那麼代碼突然不會導致分割錯誤,並且在gdb中完美工作。 編輯:在評估(int *node = malloc(116*sizeof(int));)動態分配節點[116]也解決了這個問題,但我不知道爲什麼?

評估功能:(我刪除部分代碼,否則這將是太長了)

void evaluate(int *parameter, int output[][16]) { 
    int node[116]; 
    node[0] = 0; 
    output[0][0] = !node[0]; 
    node[1] = parameter[0]; 
    output[0][1] = !node[1]; 
    output[0][2] = !node[0]; 
    ... 
    node[34] = !node[114] && !node[45]; 
    node[45] = !node[34] && !node[105]; 
    output[11][15] = node[45]; 
} 

主要功能:

int main(int argc, char *argv[]) { 
    int i; 
    int j; 
    int k; 
    int ret; 
    int parameter[8]; 
    int output[12][16]; 
    FILE *paramFile; 
    FILE *outFile; 

    paramFile = fopen(argv[1], "r"); 
    if (paramFile == NULL) { 
     printf("I couldn't open the parameter file.\n"); 
     exit(0); 
    } 
    outFile = fopen(argv[2], "ab"); 
    if (outFile == NULL) { 
     printf("Something went wrong with the output file.\n"); 
     exit(0); 
    } 
    while(1){ 
     for(i=0;i<8;i++){ 
      ret=fscanf(paramFile, "%d", &parameter[i]); 
      printf("parameter: %d\n", parameter[i]); 
     } 
     if(ret!=1){ 
      break; 
     } 
     for(j=0;j<12;j++){ 
      for(k=0;k<16;k++){ 
       output[j][k] = 2; 
      } 
     } 
     evaluate(parameter,output); 
     printf("Evaluation is done. \t %d\n",i); 
     for(j=0;j<12;j++){ //SEG FAULT HERE 
      for(k=0;k<16;k++){ 
       fprintf(outFile, "%d", output[j][k]); 
      } 
      fprintf(outFile,"\n"); 
     } 
     fprintf(outFile,"\n\n\n"); 
    } 
    printf("Closing files\n"); 
    fclose(paramFile); 
    fclose(outFile); 
    return 0; 
} 
+0

116個節點,116+個輸出:D這是令人困惑的....我想想命名(這不能解決問題,但會使這種方式更容易遵循) – 2013-03-21 08:58:49

+0

你應該強烈考慮使用Valgrind來跟蹤緩衝區溢出問題。 – 2013-03-21 09:01:12

+0

在你的代碼中是int類型的輸出[12] [16],還是你只是在你的問題中使用int來簡化?如果輸出是指向某種類型的指針,那麼問題將出現在evaluate()中,node []在堆棧中分配,並且執行output [i] [j] = node [x]將指向指向超出範圍。 – nairdaen 2013-03-21 09:04:09

回答

0

首先,你應該檢查是否有在至少兩個參數。這也會導致分段錯誤。

if (argc < 3) 
    return -1; 

然後,在評估,因爲他們是定勢數組你應該通過參數

void evaluate(int parameter[8], int output[12][16]) { 
    ... 
} 

你也可以做到這一點

void evaluate(int *parameter, int **output) { 
    ... 
} 

我認爲段錯誤可避免使用一個在這兩個聲明。

+0

如果我更改了評價功能按照你的建議,我得到這個錯誤: 警告:從兼容的指針類型 我看着二維數組,大多數文獻似乎暗示的方式傳遞的「評估」的說法2我最初做到了。 – Cassiel 2013-03-21 09:33:04

+0

對於兩個原型,你有這個錯誤?那麼,我已經有這種奇怪的段錯誤。 只是試圖把評估的直接在主要看看你是否仍然存在分段錯誤。 – Zodoh 2013-03-21 10:12:02

+0

那麼,int **輸出描述是不編譯的,所以我不能檢查它,當試圖編譯它時,我得到以下錯誤:'警告:從不兼容的指針類型傳遞'evaluate'的參數2。 如果我把評估主體放在主體中,那麼它運行時沒有任何分段錯誤。 – Cassiel 2013-03-21 10:45:09