c - 如何将 malloc 用于二维结构数组? (总线错误 : 10)

标签 c arrays struct malloc bus-error

我正在尝试实现数独解算器。为此,我使用如下所示的结构来表示数独板上的一个单元格。然后,我声明了一个由这些结构组成的 9x9 数组来表示棋盘。

细胞结构:

struct cell{
     char value;
     unsigned int possible;
};

然后,我将结构数组声明为:

struct cell board[9][9];

我的问题是,当我尝试向数组中输入一个值(即 board[2][2].value = getchar();)时,有时它有效,而其他时候我收到此错误:

Bus error: 10

我不太确定这是什么意思...“总线错误:10”与段错误有何不同?

我正在使用 gcc 并且只是在 vim 中编辑。我的感觉是,我需要为这个数组动态分配内存。现在,我了解了如何使用 malloc 为二维数组分配内存,如下所示:

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)); 

但是我在为二维结构数组实现内存分配部分时遇到了问题。

会不会是这样的?

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,但我正在努力更好地掌握整个语言。
详细\深入解释的奖励积分!

谢谢!

编辑 好的,感谢大家的宝贵建议,我仍然没有实现任何动态内存分配,但是,根据要求,这里是产生总线错误的代码:

 /* 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 }

如您所见,我已将 value 的数据类型更改为 int 以匹配 getchar() 返回类型。但是我的代码仍然产生奇怪的运行时错误/结果。例如,在 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

任何关于如何清理丑陋的双 getchar() 业务的建议也将不胜感激。
谢谢大家!

编辑第二条 问题出在那些 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     }

感谢大家的帮助和意见,我将实现你们提出的许多建议,并且仅从这个问题中就学到了很多东西!

编辑三

最后一个问题!

虽然我的原始问题已解决,但对于通过动态分配内存来实现矩阵是否会更好,是否有人有强烈的意见或推理?

我想,我会保留它,因为它可以工作,但由于矩阵相当大,动态分配是否是更好的编程实践?

最佳答案

getchar 返回代表一个字符的代码;您必须添加将其转换为数字的代码。例如,考虑以下代码:

printf("\nRow: ");
row = getchar();
printf("Column: ");
getchar();

当用户键入“hehe”而不是程序期望的 11 时会发生什么?该程序将获取he的ASCII码,将它们分配给rowcol,然后访问out-超出范围的数组元素。

实际上,普通输入也是如此!用户输入1,程序获取ASCII码(49)并执行一些内存溢出:

board[49-1][49-1].value = 53;

要解决此问题,请将字符代码转换为数字:

if (row >= '1' && row <= '9')
    row -= '0'; // a common C hack for converting a character-code to a number
else
    printf("Bad input"); // not a proper error handling, just an example

col -= '0'; // 1 line for brevity; you must do the same code as above

value = getchar();
value -= '0'; // same as above

board[row-1][col-1].value = value;

关于c - 如何将 malloc 用于二维结构数组? (总线错误 : 10),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10503373/

相关文章:

c - 冒泡排序双向链表

sql - 如何获取 3 维数组的最小值或最大值?

Java - 参数和增强的 For 循环复制问题

javascript - 带 JQuery 的工具提示事件和带 id 的数组

C#根据特定的结构成员值从数组中获取结构

android - i2c 设备驱动程序 init 未被调用

c - 为什么同样的程序在 linux 2.6.32 中比 2.6.18 慢?

c - 如何将结构属性作为参数传递

pointers - 我如何在 Go 中做一个文字 *int64?

c - 如何修复此结构/链表脚本中的不兼容类型?