【问题标题】:Why calling function second time is increasing column count by 5 times?为什么第二次调用函数会将列数增加 5 倍?
【发布时间】:2023-01-28 16:25:57
【问题描述】:

我是 C 编码的新手,对动态分配了解不多。我正在做一项作业。我正在用 c 开发贪吃蛇游戏。下面是我的代码的实现:

typedef struct snake_t {   
    unsigned int tail_row;
    unsigned int tail_col;
    unsigned int head_row;
    unsigned int head_col;            
    bool live;
} snake_t;
                
typedef struct game_state_t {
    unsigned int num_rows;
    char** board;
    unsigned int num_snakes;
    snake_t* snakes;
} game_state_t;
                
game_state_t* create_default_state() {
    // TODO: Implement this function.
    game_state_t *defaultState = (game_state_t*)malloc(sizeof(game_state_t));
    defaultState->num_rows = 18;
    defaultState->board = malloc(18 * sizeof(char *));
    
    for (int i = 0; i < 18; i++) {
        defaultState->board[i] = malloc(20 * sizeof(char));
    }
                  
    for (int i = 0; i < 18; i++) {
        for (int j = 0; j < 20; j++) {
            if (i == 0 || j == 0 || i == 18 - 1 || j == 20 - 1) {
                defaultState->board[i][j] = '#';
            }
            else {
                defaultState->board[i][j]=' ';
            }
        }
    }
                  
    defaultState->num_snakes = 1;
    defaultState->snakes = (snake_t*)malloc(sizeof(snake_t));
    defaultState->board[2][9] = '*';
    defaultState->snakes->tail_row = 2 ;
    defaultState->snakes->tail_col = 2 ;
    defaultState->snakes->head_row = 2 ;
    defaultState->snakes->head_col = 4 ;
    defaultState->board[2][2] = 'd';
    defaultState->board[2][3] = '>';
    defaultState->board[2][4] = 'D';
    defaultState->snakes->live = true;

    return defaultState;
}
                
game_state_t* actual_state = create_default_state();
game_state_t* expected_state = create_default_state();

actual_state 具有正确的行数和列数,即分别为 18 和 20,但 expected_state 将列增加 5。当我打印 actual_state->board[0] 的 strlen 时,它给出 20,但是当我打印 expected_state->board[0 的 strlen 时] 给出 25。另外,当我尝试通过 gdb 调用函数打印在 expected_state->board[0] 上进行调试时,它说重复“0x00577784 <重复 20 次>,'#\n#!' ”。 我无法发现错误。为什么第二次调用函数会将列大小增加 5?

【问题讨论】:

  • 当我打印 actual_state->board[0] 的 strlen“。board 条目不是字符串。C 中的字符串需要以 NUL 终止,看起来您的条目不是。这也是为什么我们需要将您的完整代码视为 minimal reproducible example,包括确切的测试/调试代码你从中得出结论。
  • 这里的关键:最小的.
  • 注意:您有一个非常特殊的习惯,即在行尾的; 之前添加一个空格。虽然编译器不关心,但这会使您的代码毫无理由地脱颖而出,并且可以将注意力从实际问题上移开。请记住,C 程序员是高度即使是最微小的异常也很敏感,因为这种语言不能保护你免受小错误的影响,比如使用=而不是==

标签: arrays c memory dynamic allocation


【解决方案1】:

如前所述,由于“board”字符数组末尾可能有也可能没有空终止符这一事实,您可能在字符串长度中遇到未定义的行为。

当我将您的代码复制到我的 Linux 虚拟机中并将“实际”和“预期”游戏状态结构的创建放入“主要”函数时,我发现两者之间“棋盘”字符数组的大小没有差异结构。这可能只是由于我的环境,以及字符串长度的“幸运”(这可能是未定义行为的结果之一)。

有了这个,我在你的函数中添加了一些字符数组初始化,以确保字符数组有一个空终止符('

【解决方案2】:

我有你的答案,虽然可能有点太晚了!

for (int i = 0; i < 18; i++)
{
    for (int j = 0; j < 20; j++)
    {
        if (i == 0 || j == 0 || i == 18 - 1 || j == 20 - 1)
        {
            defaultState->board[i][j]='#';
        }
        else
        {
            defaultState->board[i][j]=' ';
        }
    }
}

所以你的代码中有上面的代码部分。修复它所需要做的就是添加defaultState-&gt;board[i][20] = '

猜你喜欢
  • 2013-04-08
  • 1970-01-01
  • 2023-01-22
  • 1970-01-01
  • 2019-07-24
  • 2021-07-23
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多