数独ソルバーを実装しようとしています。これを行うには、以下に示す構造体を使用して、数独ボードのセルを表します。次に、これらの構造体の 9x9 配列を宣言して、ボードを表します。
セル構造:
struct cell{
char value;
unsigned int possible;
};
次に、structs の配列を次のように宣言します。
struct cell board[9][9];
私の問題は、配列に値を入力しようとすると (つまり、board[2][2].value = getchar();)、うまくいくこともあれば、次のエラーが発生することもあります。
Bus error: 10
これが何を意味するのかよくわかりません... "Bus error: 10" はセグメンテーション違反とどう違うのですか?
私はgccを使用していて、vimで編集しています。私の気持ちは、この配列にメモリを動的に割り当てる必要があるということです。これで、malloc を使用して 2 次元配列にメモリを割り当てる方法がわかりました。次のようになります。
int ** Array;
Array = (int**) malloc(x_size*sizeof(int*));
for (int i = 0; i < x_size; i++)
Array[i] = (int*) malloc(y_size*sizeof(int));
しかし、構造体の 2 次元配列のメモリ割り当て部分を実装するのに問題があります。
こんなものだろうか。
struct cell** board;
board = (struct cell**) malloc(x_size*sizeof(struct cell**));
for(int i=0; i< x_size; i++)
board[i] = (struct cell*) malloc(y_size*sizeof(struct cell));
この「 sizeof(struct cell) 」が、本来あるべきメモリ量を適切に割り当てていないことに注意しています。
どんな助けでも大歓迎です!私は C にかなり慣れていません (C++ は私の母国語です)。組み込み C をかなり使用しましたが、言語全体をよりよく理解しようとしています。
詳細\詳細な説明のボーナス ポイント!
ありがとう!
編集 OK、素晴らしい提案をしてくれたみんなに感謝します。私はまだ動的メモリ割り当てを実装していませんが、要求に応じて、バスエラーを生成しているコードは次のとおりです。
/* only code being used in solver.h*/
29 /* structure to describe a cell */
30 struct cell{
31 int value;
32 unsigned int possible;
33 };
/*solver.c*/
4 #include <ctype.h>
5 #include <stdio.h>
6 #include "solver.h"
7
8
9 struct cell board [9][9];
10
11
12 int main(){
13 initialize_board();
14 print_board();
15 setup_board();
16 print_board();
17 return 0;
18 }
19
20 void print_board(){
21 int i=0, j=0;
22 for(i = 0; i<9; i++){
23 for(j = 0; j<9; j++)
24 printf(" %d",board[i][j].value);
25 printf("\n");
26 }
27 }
28
29 void initialize_board(){
30 int i = 0, j = 0;
31
32 for(i = 0; i<9; i++)
33 for(j = 0; j<9; j++){
34 (board[i][j]).value = 0;
35 (board[i][j]).possible = 0x1FF;
36 }
37 }
38
39 void setup_board(){
40 int row=0, col=0, val = 0;
41 char another = 'Y';
42
43 printf("Board Initial Setup.\nEnter the row and column number of the value to be entered into the board.");
44 printf("\nRow and Column indexes start at one, from top left corner.");
45 while(another == 'Y'){
46 printf("\nRow: ");
47 row = getchar();
48 printf("Column: ");
49 getchar();
50 col = getchar();
51 printf("Value: ");
52 getchar();
53 (board[row-1][[col-1]).value = getchar();
54 printf("Enter another value? (y/n): ");
55 getchar();
56 another = toupper(getchar());
57 getchar();
58 }
59 }
ご覧のとおり、getchar() の戻り値の型と一致するように、値のデータ型を int に変更しました。しかし、私のコードは依然として奇妙な実行時エラー/結果を生成しています。たとえば、setup_board の while ループの最初の反復で、Row:1、Col:1、Value:5 と入力できます。その後、'n' を入力して終了すると、ボードの上部に 5 が印刷されます。ただし、これは当てはまりません。出力される行列は、initialize_board() が呼び出された後もその状態のままです。
出力:
Board Initial Setup.
Enter the row and column number of the value to be entered into the board.
Row and Column indexes start at one, from top left corner.
Row: 1
Column: 1
Value: 4
Enter another value? (y/n): n
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
また、他のマトリックス座標を入力すると、バスエラーが発生します: 出力:
Board Initial Setup.
Enter the row and column number of the value to be entered into the board.
Row and Column indexes start at one, from top left corner.
Row: 5
Column: 5
Value: 5
Bus error: 10
その醜い double getchar() ビジネスをクリーンアップする方法についてのアドバイスもいただければ幸いです。
みんな、ありがとう!
EDIT NUMBER 2 問題は、これらの getchar() にありました.... 実際の数値そのものではなく、数値を表す整数の ASCII コードを返すことに気づきませんでした。これを修正するために私が行ったことは次のとおりです。
47 while(another == 'Y'){
48 valid=0;
49 while(!valid){
50 printf("\nRow: ");
51 row = getchar() - '0'; /* convert ASCII character code to actual integer value */
52 getchar(); /*added to remove extra newline character from stdin */
53 printf("Column: ");
54 col = getchar() - '0';
55 getchar(); /*remove \n */
56 printf("Value: ");
57 val = getchar() - '0';
58 getchar(); /*remove \n */
59 if(val >9 || val<1 || col>9 ||col<1 || row>9 || row<1)
61 printf("\nInvalid input, all values must be between 1 and 9, inclusive");
62 else
63 valid = 1;
64 }
65 board[row-1][col-1].value = val;
66 printf("Enter another value? (y/n): ");
67 another = toupper(getchar());
68 getchar(); /*remove \n */
69 }
皆さんのご協力とご意見に感謝します。皆さんが行った提案の多くを実装し、この質問から多くのことを学びました!
編集番号 3
最後に 1 つの質問です。
私の最初の問題は解決されましたが、メモリを動的に割り当てることによってマトリックスを実装する方が良いかどうかについて、強い意見や推論を持っている人はいますか?
動作するのでそのままにしておきますが、マトリックスがかなり大きいので、動的に割り当てる方がプログラミングの練習に適しているでしょうか?