二维结构体数组内存分配错误致段错误,求Tetris棋盘初始化修复方案
修复俄罗斯方块棋盘初始化的段错误问题
以下是你的代码中导致段错误的核心问题及修复方案:
错误点与修复说明
- 变量名不匹配:棋盘结构体
str_board定义的成员是row和col,但初始化函数里误用了row_number、row_column、column_number,直接导致访问非法内存地址。 - malloc语法与类型错误:两处
malloc都缺少闭合右括号;且每行内存应分配sizeof(box)而非sizeof(box*)——因为每行是box结构体数组,不是指向box的指针数组。 - rand函数调用错误:
rand % 2应改为rand() % 2,缺少函数调用括号会导致用函数地址做取模运算,结果完全错误。 - 成员名拼写错误:结构体定义的是
special,代码里写成了带重音的spécial,会触发无效内存写入。 - 缺失内存分配检查:未判断
malloc返回值,内存分配失败时会继续执行后续代码引发崩溃。
修复后的完整代码
#include <stdlib.h> #include <stdio.h> #include <time.h> // 假设tetromino为指针类型,若为结构体需调整初始化逻辑 typedef struct str_tetromino tetromino; typedef struct str_box { int special; tetromino *t; } box; typedef struct str_board { int row; int col; box **game_grid; } *board; void init_game_grid(board b) { // 前置参数校验 if (b == NULL || b->row <= 0 || b->col <= 0) { fprintf(stderr, "无效的棋盘参数\n"); return; } // 初始化随机数种子(仅需在程序启动时调用一次) static int rand_seeded = 0; if (!rand_seeded) { srand(time(NULL)); rand_seeded = 1; } int count = 8; // 分配行指针数组 b->game_grid = malloc(b->row * sizeof(box*)); if (b->game_grid == NULL) { perror("行指针数组分配失败"); return; } for (int i = 0; i < b->row; i++) { // 分配每行的box结构体数组 b->game_grid[i] = malloc(b->col * sizeof(box)); if (b->game_grid[i] == NULL) { perror("单行棋盘内存分配失败"); // 回滚已分配内存避免泄漏 for (int j = 0; j < i; j++) { free(b->game_grid[j]); } free(b->game_grid); b->game_grid = NULL; return; } for (int j = 0; j < b->col; j++) { // 初始化方块成员 b->game_grid[i][j].t = NULL; int r = rand() % 2; if (r == 1 && count > 0) { count--; b->game_grid[i][j].special = 1; } else { b->game_grid[i][j].special = 0; } } } }
额外注意事项
- 若
tetromino是结构体而非指针,b->game_grid[i][j].t = NULL;需改为结构体初始化,例如用memset(&b->game_grid[i][j].t, 0, sizeof(tetromino));。 - 游戏结束时需释放棋盘内存:先循环释放每行的
box数组,再释放行指针数组。
内容的提问来源于stack exchange,提问作者R B
相关产品推荐
相关产品推荐

