C语言游戏2D数组Save/Load存档读档功能异常问题求助
问题排查与修复方案
核心问题点
- 空指针判断位置完全错误:
fopen之后第一时间没有判断文件指针是否为空,直接执行fwrite/fread操作,如果文件打开失败(比如路径无权限、文件名非法)会直接触发空指针访问崩溃,后续的空指针判断完全没有作用。 - 二维数组写入逻辑错误:如果你的
board是动态申请的int**类型二维数组,直接对board指针执行fwrite只会写入指针数组的地址值,不会写入实际的游戏数据;如果是静态二维数组,你需要传入总元素个数(行数*列数)作为fwrite的第三个参数,而非单个size。 - 缺少IO操作返回值校验:
fwrite、fread、fclose的返回值都没有校验,无法定位是写入失败还是读取失败、具体失败了多少字节。 - 二进制写入的认知误区:你用
wb二进制模式写入的内容本身就是非文本格式,直接打开txt文件查看会显示乱码是正常现象,只要读档能恢复数据就符合要求,如果需要可读的文本存档需要换成fprintf按行写入。
修复后的代码示例
修复后Save函数
// 假设size是总元素个数 = 行数 * 列数,如果是二维数组请自行调整参数传入行列值 void save(char *filename) { FILE *fp = fopen(filename, "wb"); // 打开文件后第一时间判空 if(fp == NULL) { // 可自行添加错误打印逻辑定位问题 return; } // 校验写入返回值 if(fwrite(&size, sizeof(size), 1 , fp) != 1) { fclose(fp); return; } // 如果是静态二维数组int board[ROW][COL],直接写没问题,第三个参数传ROW*COL // 如果是动态int** board,需要逐行写入: // for(int i=0; i<row_num; i++) { // if(fwrite(board[i], sizeof(int), col_num, fp) != col_num) { // fclose(fp); // return; // } // } if(fwrite(board, sizeof(int), size, fp) != size) { fclose(fp); return; } fclose(fp); }
修复后Load函数
void load(char *filename) { FILE *fp = fopen(filename, "rb"); if(fp == NULL) { return; } if(fread(&size, sizeof(size), 1 , fp) != 1) { fclose(fp); return; } // 动态二维数组需要先按读取到的size申请内存再读,逐行读取逻辑同save if(fread(board, sizeof(int), size, fp) != size) { fclose(fp); return; } fclose(fp); }
额外注意事项
- 如果你的
board是动态分配的二维数组,读档前需要先根据读取到的行列值完成内存申请,再执行读取操作,否则会写入到野指针地址。 - 尽量避免用全局变量传
size和board,建议改成函数参数传入,降低代码耦合。
内容的提问来源于stack exchange,提问作者Joe LaBianca
相关产品推荐
相关产品推荐

