不明确的分段故障返回139

时间:2014-11-03 00:06:16

标签: c c89

我尝试编写一个数独求解器 在solveSudoku中调用getPossibleElements后,我总是遇到分段错误。 如果我删除此行,则不会出现错误。

我的代码

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define SUDOKU_X 8
#define SUDOKU_Y 8
#define MAX_FILENAME 50
#define MAX_POSSIBILITIES 8

typedef enum bool {false, true} bool;

void printPossibilities (bool numbers[], const int pos_x, const int pos_y) {
  int i = 0;

  for (i = 0; i <= MAX_POSSIBILITIES; i++) {
    if (numbers[i]) {
      printf("%d ", (i+1));
    }
  }
}

void getPossibleElements (bool numbers[],int a[][SUDOKU_Y], const int pos_x, const int pos_y) {
  int x = 0;
  int y = 0;
  int i = 0;
  int j = 0;
  int tmp = 0;

  for (x = 0; x <= MAX_POSSIBILITIES; x++) {
    numbers[x] = true;
  }

  /* row */
  for (x = 0; x <= SUDOKU_X; x++) {
    if (a[pos_y][x] > 0) {
        printf("ROW->a[%d][%d]\n",pos_y,x);
        printf("ROW->%d\n",a[pos_y][x]-1);
      numbers[a[pos_y][x]-1] = false;
    }
  }
  /* coloumn */
  for (y = 0; y <= SUDOKU_Y; y++) {
    if (a[y][pos_x] > 0) {
        printf("coloumn->a[%d][%d]\n",y,pos_x);
        printf("coloumn->%d\n",a[y][pos_x]-1);
      numbers[a[y][pos_x]-1] = false;
    }
  }
  /* field */
if (pos_x <= 2 && pos_y <= 2) {
    x = 0;
    y = 0;
  }
  else if (pos_x <= 5 && pos_y <= 2) {
    x = 3;
    y = 0;
  }
  else if (pos_x <= 8 && pos_y <= 2) {
    x = 6;
    y = 0;
  }
  else if (pos_x <= 2 && pos_y <= 5) {
    x = 0;
    y = 3;
  }
  else if (pos_x <= 5 && pos_y <= 5) {
    x = 3;
    y = 3;
  }
  else if (pos_x <= 8 && pos_y <= 5) {
    x = 6;
    y = 3;
  }
  else if (pos_x <= 2) {
    x = 0;
    y = 6;
  }
  else if (pos_x <= 5) {
    x = 3;
    y = 6;
  }
  else if (pos_x <= 8) {
    x = 6;
    y = 6;
  }

  printf("DB!!! x=%d y=%d\n", x,y);


  for (j = y; j < (y+3); j++) {
    for (i = x; i < (x+3); i++) {
      if (a[j][i] > 0) {
        printf("FIELD->a[%d][%d]\n",j,i);
        printf("FIELD->%d\n",(a[j][i])-1);
        numbers[(a[j][i])-1] = false;
      }
    }
  }
  printf("db");
}



void printSudoku (int a[][SUDOKU_Y]) {
    int i = 0;
    int j = 0;
    printf("-------------------------------\n");
    for (j = 0; j <= SUDOKU_X; j++)
    {
      for (i = 0; i <= SUDOKU_Y; i++) {
        if (i == 0) {
          printf("|");
        }
        printf(" %d ",a[j][i]);
        if (i == 2 || i == 5 || i == 8) {
          printf("|");
        }
      }
      printf("\n");
      if (j == 2 || j == 5) {
        printf("|-----------------------------|\n");
      }
    }
    printf("-------------------------------\n");
}/* printSudoku */

bool solveSudoku (int a [][SUDOKU_Y]) {
  bool numbers[MAX_POSSIBILITIES];
  int x = 0;
  int y = 0;

  printSudoku(a);
  getPossibleElements(numbers,a,x,y);
  printPossibilities(numbers,x,y);
  return true;
}
void readFiletoArray (const char * fileName, int a[][SUDOKU_Y])
{
    FILE *fp = fopen(fileName,"r");
    int i = 0;
    int j = 0;
    int val0 = 0;
    int val1 = 0;
    int val2 = 0;

    if( fp == NULL ) {
      perror("Error while opening the file.\n");
      exit(EXIT_FAILURE);
    }

    while(fscanf(fp, "%d %d %d", &val0, &val1, &val2) > 0) {
      a[j][i++] = val0;
      a[j][i++] = val1;
      a[j][i++] = val2;
      if (i >= 8) {
        i = 0;
        j++;
      }
    }
    fclose(fp);
} /* readFiletoArray */

int main (int argc, char * argv []) {
  int a[SUDOKU_X][SUDOKU_Y];
  char fileName[MAX_FILENAME];
  bool numbers[MAX_POSSIBILITIES];
  bool success = false;

  if(argc == 2) {
    strncpy(fileName, argv[1], MAX_FILENAME-1);
    fileName[MAX_FILENAME] = '\0';
  }
  else {
    printf("ERROR: Invalid Parameter\n");
    exit(EXIT_FAILURE);
  }
  readFiletoArray(fileName, a);

  success = solveSudoku(a);

  printf("DB");
  exit(EXIT_SUCCESS);
} /* Main */

sudoku.txt(程序参数)

0 5 9 0 4 0 2 0 0
0 1 0 0 5 0 0 0 7
4 0 0 3 2 9 0 1 5
3 2 0 1 0 0 9 0 0
0 0 7 4 0 6 5 0 0
0 0 4 0 0 5 0 7 8
6 9 0 5 0 3 0 0 4
5 0 0 0 6 0 0 3 0
0 0 8 0 1 0 6 5 0

THX

1 个答案:

答案 0 :(得分:2)

乍一看,这是因为你在不同的地方跑了阵列的末尾。

for (x = 0; x <= MAX_POSSIBILITIES; x++) { // 0,1,2...8

看到你有<=吗?这是你的问题。

numbers声明为bool numbers[MAX_POSSIBILITIES];,C中的数组索引从0开始,然后转到length - 1。在这种情况下,零到七,但您正尝试访问numbers[8]

你在其他地方遇到同样的问题。 a被声明为

int a[SUDOKU_X][SUDOKU_Y]; // int a[8][8];

并且在getPossibleElements中你正在从0到8进行迭代,如下所示:

for (x = 0; x <= SUDOKU_X; x++) { 
...
for (y = 0; y <= SUDOKU_Y; y++) {

...因此再次运行阵列的末尾。

printPossibilities中的相同优惠。

MAX_POSSIBILITIESSUDOKU_XSUDOKU_Y更改为9中的#define,并通过

从0到8进行迭代
for (x = 0; x < SUDOKU_X; x++) { // 0,1,2...8 

还有一件事。您也应修复fileName内容。同样的交易。数组中的最后一个索引是length - 1,而不是length。如果您在编译时发出警告,可能会提到这个警告。

if (argc == 2) {
    strncpy(fileName, argv[1], MAX_FILENAME - 2); // was MAX_FILENAME - 1
    fileName[MAX_FILENAME - 1] = '\0'; // was [MAX_FILENAME]
}