了解内存分配和核心转储错误

时间:2016-05-16 10:05:45

标签: c segmentation-fault

我对内存分配感到困惑。

我想用随机数填充数独结构,然后检查一个9个数字的框是否正确。

#define SUDOKU_SIZE 9 
typedef struct 
{ 
   int grid[SUDOKU_SIZE][SUDOKU_SIZE]; 
} sudoku_t;

int main(int argc, char const *argv[]){
    sudoku_t *s=malloc(sizeof s);
    s->grid[0][0]=6;//manualy setting the value of the sudoku
    ...
    s->grid[8][8]=7;
    fill_sudoku_test(s);//fill s, a feasible Sudoku with random number
    int k, l;
    for(k=0;k<SUDOKU_SIZE;k+=3){
        for(l=0;l<SUDOKU_SIZE;l+=3){
            if(correct_box(s,k,l))//check if a box of 3 by 3 contains 9 differents numbers
                printf("Box correct at position :%d and %d\n",k,l);
         }
    }
    free(s);
    return EXIT_SUCCESS;
}

当我编译这段代码时,我收到了一个核心转储错误。

如果有人得到解决方案,我很感兴趣

修改

以下是其他功能:

void fill_sudoku_test(sudoku_t *s){
   int k, l;
   time_t t;
   srand((unsigned) time(&t));
   for(k=0;k<SUDOKU_SIZE;k++){
       for(l=0;l<SUDOKU_SIZE;l++){
           if(!(s->grid[k][l])) {
               s->grid[k][l]=rand()%SUDOKU_SIZE+1;
           }            
       }
   }
}


int correct_tab(int value[]){
   int i;
   int tab[9];
   for(i=0;i<SUDOKU_SIZE;i++){
      tab[i]=0;
   }
   for(i=0;i<SUDOKU_SIZE;i++){
      if(tab[value[i]-1]==1){
        return 0;
      }
      else{
        tab[value[i]-1]=1;
      }
   }
   return 1;
}

int correct_box(sudoku_t *s, int i, int j){
   int tab[SUDOKU_SIZE];
   int count=0;
   int k,l;
   for(k=0;k<3;k++){
      for(l=0;l<3;l++){
         tab[count]=s->grid[i+k][j+l];
      }
   }
   return (correct_tab(tab));
}

3 个答案:

答案 0 :(得分:5)

sudoku_t *s=malloc(sizeof s);

应该是

sudoku_t *s=malloc(sizeof(sudoku_t));

sudoku_t *s=malloc(sizeof(*s));

修改

在函数correct_tab中,value[i]可以是(并且是)0。然后:

tab[value[i]-1]=1;

if(tab[value[i]-1]==1)

访问数组越界。

编辑2

correct_tab value数组中没有为整个SUDOKU_SIZE引入数组,那么数组的某些值是未定义的。

至少可以将其声明为:

int tab[SUDOKU_SIZE] = {0};

<强> EDIT3

回答你的意见:

您的初始化是正确的:初始号码介于19之间。

问题是从correct_tab调用correct_box正在传递tab,一个本地(堆栈分配)数组。这意味着一件大事:

  • 它的值不是0.这些值是由于的值而产生的 堆栈分配。

使用我的EDIT2代码,你可以为数组的所有值设置0。

BTW您的correct_tab函数循环整个制表符数组,其中只从您的sudocu_t结构矩阵中提取一些值。 发生这种情况的原因是:

  1. count变量correct_box函数始终为0。每次将值设置为tab数组时,都必须加入。
  2. 您应该将count值传递给correct_tab函数,以便仅允许在实际插入的值上循环。

答案 1 :(得分:1)

分配时:

sudoku_t *s=malloc(sizeof s);

这仅分配足以存储指针的内存。你可能意味着:

sudoku_t *s=malloc(sizeof(*s));

除此之外,您还需要使用调试器来识别代码的哪一部分实际触发了分段错误。

答案 2 :(得分:0)

第一个问题在于这一行:

sudoku_t *s=malloc(sizeof s);

这意味着malloc分配的内存等于指针的大小,根据机器的不同,可能是4个字节或8个字节。

理想情况下,您期望的是分配结构的大小,所以这应该是:

sudoku_t *s = (sudoku_t *) malloc(sizeof(sudoku_t));