康威生命游戏的 ANSI C 实现

ANSI C implementation of Conway's Game of Life

我目前正在尝试通过实现控制台版本的“Conway's Game of Life”来学习 C 语言。 我有一个名为 'set_dead_state' 的函数,它只是创建一个 0 的二维数组:

void create_game_board(int *dest[], int width, int height) {
  for(int i = 0; i < height; i++) {
    dest[i] = malloc(sizeof(int)*width);
    memset(dest[i], 0, width*sizeof(int));
  }
}

widthheight 设置为 10,我遍历数组并使用此函数将每个 0 打印为 " - "

void print_game_board(int* board[], int width, int height) {
  for(int y = 1; y < height+1; y++) {
    for(int x = 1; x < width+1; x++) {
      if(board[y][x] == DEAD)
        printf(" - ");
      else
        printf(" # ");
    }
    printf("\n");
  }
}

它按预期输出:

 -  -  -  -  -  -  -  -  -  - 
 -  -  -  -  -  -  -  -  -  - 
 -  -  -  -  -  -  -  -  -  - 
 -  -  -  -  -  -  -  -  -  - 
 -  -  -  -  -  -  -  -  -  - 
 -  -  -  -  -  -  -  -  -  - 
 -  -  -  -  -  -  -  -  -  - 
 -  -  -  -  -  -  -  -  -  - 
 -  -  -  -  -  -  -  -  -  - 
 -  -  -  -  -  -  -  -  -  - 
memory freed successfully

然后我使用这个函数释放了在 create_game_board 函数中分配的内存:

void free_array_memory(int *arr[]) { 
  for(int i = 0; i < sizeof(*arr)/sizeof(arr[0]); i++) 
    free(arr[i]);
}

我的问题是关于我第一次尝试实现 create_game_board 函数,它看起来像这样:

// This does not work.
void create_game_board(int* dest[], int width, int height) {
  for(int i = 0; i < height; i++) {
    int row[width]; 
    memset(dest, 0, width*sizeof(int));
    dest[i] = row;
  }
}

下面是我使用此版本的函数时输出到控制台的内容,以及我在尝试释放内存时收到的消息(宽度和高度是相同的值)。我希望它能像我一开始提到的那样工作。为什么这个功能不起作用?

 -  -  -  -  -  -           - 
 -  -  -  -  -  -           - 
 -  -  -  -  -  -           - 
 -  -  -  -  -  -           - 
 -  -  -  -  -  -           - 
 -  -  -  -  -  -           - 
 -  -  -  -  -  -           - 
 -  -  -  -  -  -           - 
 -  -  -  -  -  -           - 
 -  -  -  -  -  -           - 
free(): invalid pointer
exited, aborted

在您之前的实现中,您将 src 中的指针设置为 row 的第一个元素的地址。但是 - row 是栈上的变量,而不是堆上的变量;当弹出堆栈时,它会“取消分配”(并被其他函数用作堆栈区域的一部分)。你不能free()那个地址。

然而,这两种实现方式都存在问题:

  • “设置状态”的函数不应分配内存;这很令人惊讶(打破 principle of least astonishment)。您可以调用函数 create_game_board() 或其他东西。
  • 没有充分的理由进行 height 不同的分配。只需分配width*height个元素一次,并设置src个元素指向该区域的不同点。
  • src 是游戏板行指针参数名称的错误选择。它不是任何东西的“来源”。
  • 为什么你的评论说板子是 10x10,而它的尺寸是动态的?
  • 棋盘是长方形的还是正方形的?如果它是正方形,则对宽度和高度使用相同的变量名称(例如 'dimension' 或 'order' 或其他名称)。