2013-03-21 136 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

相关问题