具有二维数组问题的C游戏板

时间:2019-01-29 01:50:00

标签: c arrays init

更新: 修复了悬挂式指针,解决了很多问题。还颠倒了我的Game_board init。然后,我创建了一个移动方法来测试片段。

建议:小心悬挂指针和内存分配。

2 个答案:

答案 0 :(得分:0)

欢迎使用堆栈溢出。通常,我们更希望您将代码粘贴到此处,而不是链接到该代码。 (随着时间的推移,链接可能会过时)。您还应该描述所看到的错误消息,以确保我们都在同一页面上。

您可能有多个问题,但是首先肯定是在game_piece_to_label中您使用的是未初始化的指针。

char* game_piece_to_string(struct game_piece* piece)
{
    char* tempLabel;
    strcpy(tempLabel, game_piece_get_label(piece));

您需要分配一些内存并将其分配给tempLabel。就目前而言,您正在写随机存储器,对我来说这会导致段错误。

答案 1 :(得分:0)

使用未初始化的指针

一个大问题是您将char *tempLabel;用作未初始化的指针。 (它指向什么地方?它的值保留哪个有效内存地址?)可以确保将数据复制到SegFault。相反,您需要验证game_piece_get_label(piece)的长度并使用length + 1分配 malloc, calloc or realloc个存储字符,例如。

例如:

char *game_piece_to_string (struct game_piece *piece)
{
    char *tempLabel;    /* uninitialized pointer */
    size_t len = strlen (game_piece_get_label(piece));

    tempLabel = malloc (len + 1);
    if (tempLabel == NULL) {
        perror ("malloc-tempLabel");
        return NULL;
    }
    memcpy (tempLabel, game_piece_get_label(piece), len + 1);

    if (len > 3)
        tempLabel[1] = '\0';
    for (size_t i = 3; i > len; i--)
        strcat(tempLabel, " ");

    return tempLabel;
}

请注意,您要对条件进行的操作以及使用sizeof (a_pointer)进行的循环没有什么意义。假定您想要tempLabel length

问题分配董事会

您的 pointer-to-pointer-to struct game_piece分配几乎是向后的。您必须先分配row个指针,然后每行分配colstruct game_piece。然后,您将在每个[i][j]上为一个struct game_piece分配存储空间-在这里,您决定将char label[30];作为单成员放入结构中,这会使引用{{1} }。

进行更改,您可以执行以下操作:

label

所有这些都表明您要么(1)在没有启用警告的情况下编译代码,要么(2)有意识地忽略了编译器正在生成的警告。对于gcc / clang,至少要在您的编译器选项中添加void game_board_init(struct game_board* game_board, int rows, int cols) { /* allocate row number of pointers */ game_board->board = malloc (sizeof(*game_board->board)*rows); /* allocate col number of **game_board->board per row * (e.g. col * sizeof (struct game_piece) per row) */ for (int i = 0; i < rows; i++){ game_board->board[i] = malloc(sizeof(struct game_piece) * cols); } game_board->row = rows; game_board->col = cols; for (int i=0; i < rows; i++){ printf("\n"); for (int j=0; j < cols; j++) { game_piece_init_default(&game_board->board[i][j]); printf("%s ",game_board->board[i][j].label); } } } ,对于VS,请添加-Wall -Wextra -pedantic,并且不要接受代码,直到它编译没有警告。让您的编译器帮助您编写更好的代码。 (从长远来看,这将为您节省大量时间)

您还需要看看How to debug small programs并和鸭子说话...真的,这对/W3很有帮助

启用编译器警告,查看调试链接,然后编辑您遇到的任何其他特定区域并将其添加添加到您的问题底部,我们很乐意为您提供进一步的帮助。

进行上述更改,并添加以下“存根”以使未完成的:)中未使用的变量的警告静音,例如

game_board_move_piece

我可以使用以下代码使用gcc编译您的代码:

    if (game_board || src_row || src_col || dest_row || dest_col) {}

没有警告。您需要进行一些其他调试,如下所示:

使用/输出示例

gcc -Wall -Wextra -pedantic -Wshadow -std=c11 -Ofast -o gb_init gb_init.c

那是与“鸭子”的对话开始的地方...

使用的完整测试代码

以下是我以前不加警告地进行编译并生成上面输出的内容。

$ ./bin/game_board_init
Please enter the number of rows.
3
Please enter the number of columns.
3

--- --- ---
--- --- ---
--- --- --- Please enter a label for a new piece. Enter "Q" when done.
a
Please enter a row for the piece.
1
Please enter a column for the piece.
1
New piece "a" added.
Please enter a label for a new piece. Enter "Q" when done.c
Please enter a row for the piece.
2
Please enter a column for the piece.
2
New piece "c" added.
Please enter a label for a new piece. Enter "Q" when done.b
Please enter a row for the piece.
0
Please enter a column for the piece.
0
New piece "b" added.
Please enter a label for a new piece. Enter "Q" when done.q
try again -kelly
b  ------
---a  ---
------c  Would you like to move a piece? Enter "Y" to move a piece.
Y
Please enter the piece's row.2
Please enter the piece's column.2
Please enter the piece's new row.2
Please enter the piece's new column.0
A piece is already in that space.
try again -kelly
b  ------
---a  ---
------c  Would you like to move a piece? Enter "Y" to move a piece.
n