C语言实现Game of Life时update函数导致细胞更新异常问题
问题排查
共有4处核心错误导致程序无法正常运行:
- 悬垂指针问题:
update函数中定义的new数组是栈内存局部变量,函数执行结束后内存会被系统回收,返回该数组地址属于非法内存访问,后续memcpy读取的是无效数据。 - 坐标传参错误:
neighbors函数定义的形参顺序是(grid, x, y),但调用时传入的i是Y轴行索引、j是X轴列索引,坐标顺序完全颠倒,导致邻居计算完全错误。 - 邻居计数包含自身:遍历相邻格子时没有排除当前格子本身(即
dx==0 && dy==0的情况),不符合生命游戏邻居计数规则。 - 边界判定错误:邻居范围判断写的是
dsty > 0 && dsty < MAX_Y && dstx > 0 && dstx < MAX_X,排除了索引为0的第一行和第一列,边界格子的邻居计算全部错误。
修正后完整代码
#include <stdio.h> #include <string.h> #define MAX_Y 10 /* height */ #define MAX_X 30 /* width */ int neighbors(int grid[MAX_Y][MAX_X], int y, int x) { int dx, dy, dstx, dsty; int n = 0; for (dy = -1; dy < 2; ++dy) { for (dx = -1; dx < 2; ++dx) { if (dx == 0 && dy == 0) continue; // 排除当前细胞本身 dsty = y + dy; dstx = x + dx; // 边界判断包含0索引 if (dsty >= 0 && dsty < MAX_Y && dstx >= 0 && dstx < MAX_X) { n += !!grid[dsty][dstx]; } } } return n; } void update(int grid[MAX_Y][MAX_X], int new[MAX_Y][MAX_X]) { memset(new, 0, sizeof(int[MAX_Y][MAX_X])); int i, j, n; for (i = 0; i < MAX_Y; ++i) { for (j = 0; j < MAX_X; ++j) { n = neighbors(grid, i, j); if (grid[i][j] && (n == 2 || n == 3)) new[i][j] = 1; else if (!grid[i][j] && n == 3) new[i][j] = 1; else new[i][j] = 0; } } } void draw(int grid[MAX_Y][MAX_X]) { int i, j; for (i = 0; i < MAX_Y; ++i) { for (j = 0; j < MAX_X; ++j) { putchar((grid[i][j]) ? '#' : '.'); } putchar('\n'); } } int main(void) { int map[MAX_Y][MAX_X]; int new_map[MAX_Y][MAX_X]; memset(map, 0, sizeof map); map[2][2] = 1; map[3][2] = 1; map[4][2] = 1; map[4][3] = 1; map[3][4] = 1; printf( " Game of Life v1.0\n" "Press ENTER to step.\n"); for (;;) { draw(map); update(map, new_map); memcpy(map, new_map, sizeof map); getchar(); } }
内容的提问来源于stack exchange,提问作者user14189755
相关产品推荐
相关产品推荐

