C语言分配结构体二维数组实现棋盘遇运行时错误求解决
代码改进建议及实现思路
原代码的问题分析
- 函数参数
int** board完全冗余,函数内部重新分配内存并返回指针,这个参数无实际作用 malloc类型转换错误:(int*)应改为(int**)(C中可省略强制转换,但转换时需匹配类型)- 内存分配失败后
return;不符合函数返回类型要求,应返回NULL - 未检查每行
malloc的返回值,若某一行分配失败,已分配的内存无法释放,造成内存泄漏 - 函数内打印输入提示但未读取
size的值,若调用时传入的size是未初始化的垃圾值,会引发非法内存访问
改进后的int类型二维数组代码
#include <stdio.h> #include <stdlib.h> int** makeboard(int size) { // 先校验尺寸合法性 if (size <= 0) { printf("Invalid board size\n"); return NULL; } int** board = malloc(size * sizeof(int*)); if (!board) { perror("Failed to allocate row pointers"); return NULL; } for (int i = 0; i < size; i++) { board[i] = malloc(size * sizeof(int)); if (!board[i]) { perror("Failed to allocate row data"); // 释放已分配的内存,避免泄漏 for (int j = 0; j < i; j++) { free(board[j]); } free(board); return NULL; } // 可选:初始化元素为0,避免垃圾值干扰 for (int k = 0; k < size; k++) { board[i][k] = 0; } } return board; } // 配套的内存释放函数 void freeboard(int** board, int size) { if (!board) return; for (int i = 0; i < size; i++) { free(board[i]); } free(board); }
不同的实现思路
1. 单块内存分配二维数组
将二维数组作为连续内存块分配,减少内存碎片,访问效率更高:
#include <stdio.h> #include <stdlib.h> // 返回一维指针,通过索引计算访问二维元素:board[row * size + col] int* makeboard_single(int size) { if (size <= 0) { printf("Invalid board size\n"); return NULL; } int* board = malloc(size * size * sizeof(int)); if (!board) { perror("Failed to allocate board"); return NULL; } // 初始化所有元素为0 for (int i = 0; i < size * size; i++) { board[i] = 0; } return board; } // 释放时直接调用free(board);即可
2. 使用结构体封装棋盘
适合后续扩展为自定义结构体类型的棋盘,便于维护和扩展属性:
#include <stdio.h> #include <stdlib.h> // 定义棋盘格子的结构体,可扩展更多属性 typedef struct { int value; // 示例:添加颜色、选中状态等属性 // int color; // int is_selected; } ChessPiece; // 封装整个棋盘的结构体 typedef struct { int size; ChessPiece** grid; } ChessBoard; ChessBoard* make_chessboard(int size) { if (size <= 0) { printf("Invalid board size\n"); return NULL; } ChessBoard* board = malloc(sizeof(ChessBoard)); if (!board) { perror("Failed to allocate board struct"); return NULL; } board->size = size; board->grid = malloc(size * sizeof(ChessPiece*)); if (!board->grid) { perror("Failed to allocate row pointers"); free(board); return NULL; } for (int i = 0; i < size; i++) { board->grid[i] = malloc(size * sizeof(ChessPiece)); if (!board->grid[i]) { perror("Failed to allocate row data"); // 回滚已分配内存 for (int j = 0; j < i; j++) { free(board->grid[j]); } free(board->grid); free(board); return NULL; } // 初始化每个格子的属性 for (int k = 0; k < size; k++) { board->grid[i][k].value = 0; // board->grid[i][k].color = 0; } } return board; } // 配套的释放函数 void free_chessboard(ChessBoard* board) { if (!board) return; for (int i = 0; i < board->size; i++) { free(board->grid[i]); } free(board->grid); free(board); }
3. 变长数组(VLA)(栈分配,适合小棋盘)
如果棋盘尺寸不大,可直接在栈上分配变长数组,无需手动管理内存,但注意栈空间有限(通常仅几MB):
#include <stdio.h> void makeboard_vla(int size) { // 限制尺寸避免栈溢出 if (size <= 0 || size > 1000) { printf("Invalid board size\n"); return; } int board[size][size]; // 初始化所有元素为0 for (int i = 0; i < size; i++) { for (int j = 0; j < size; j++) { board[i][j] = 0; } } // 直接使用棋盘即可,函数结束后栈内存自动释放 }
内容的提问来源于stack exchange,提问作者ildb
相关产品推荐
相关产品推荐

