You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.28 15:54:05