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

C语言结构体中二维数组内存释放 Valgrind提示未释放问题排查

问题原因分析

你的代码存在两个核心问题,共同导致了内存完全没有被释放:

  • 释放逻辑和申请逻辑的循环次数不匹配
    你在buildfield函数中为game->field申请了20个int*类型的指针,每个指针都单独申请了内存,但是在freefield函数中仅循环了传入的length值(也就是10)次,仅尝试释放前10个指针指向的内存,剩下10个指针对应的内存本身就没有被纳入释放逻辑。
  • 存在数组越界访问,程序提前崩溃,释放代码完全没有执行
    这是Valgrind显示0 frees的直接原因,你的代码有两处明确的越界访问:
  1. buildfield的初始化循环中for (int col = 0; col < 81; col++),但game->field总共只申请了20个元素,col≥20时就已经访问了非法内存,触发未定义行为,绝大多数情况下会直接导致程序段错误终止,后续的freefield、free(game)逻辑完全没有运行的机会。
  2. printfield中的数组下标写反:你内层循环j的范围是0~19,但game->field[i]仅申请了10个int元素,game->field[i][j]在j≥10时就已经越界,也会触发程序崩溃。
修复方案

你可以按照以下逻辑修改代码:

  1. 建议把行列常量用宏定义统一管理,避免魔数不匹配的问题
  2. 修正越界访问的下标
  3. 修正释放逻辑的循环次数

修改后的核心代码示例:

// 顶部加宏定义
#define FIELD_COL 20
#define FIELD_LINE 10

void buildfield(Game* game, int length)
{
    game->field = (int**)malloc((sizeof (int*)) * FIELD_COL);
    int i;
    for (i = 0; i < FIELD_COL; i++) {
        game->field[i] = (int*) malloc((sizeof (int)) * length);
    }
    // 修正col上限
    for (int line = 0; line < length; line++) {
        for (int col = 0; col < FIELD_COL; col++) {
            game->field[col][line] = 0;
        }
    }
}

void printfield(Game* game, int length)
{
    for (int i = 0; i < length; i++) {
        printf("\n");
        for (int j = 0; j < FIELD_COL; j++) {
            // 修正下标顺序
            printf("%d",game->field[j][i]);
        }
    }
}

void freefield(Game* game, int length)
{
    // 修正循环次数为申请的列数
    for (int i = 0; i < FIELD_COL; ++i) {
        free(game->field[i]);
    }
    free(game->field);
}

修改后重新编译运行,Valgrind就可以检测到所有内存都被正常释放了。

内容的提问来源于stack exchange,提问作者David To

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 05:45:02