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

实现全动态二维数组API时遭遇内存泄漏,求定位问题

问题分析与修复方案

内存泄漏的核心原因

你的代码存在两处关键问题导致内存泄漏和未定义行为:

1. allocate_array 函数的循环次数错误

函数中分配行内存的循环条件写成了 i < n,但实际应该循环 m 次(m 是二维数组的行数)。以测试用例 m=2, n=3 为例,循环会执行3次,而你只给 arr 分配了2个 int* 的空间,访问 arr[2] 属于数组越界,会触发未定义行为,同时真正需要的2行中可能有未分配的情况,后续释放时也会出错。

2. allocate_array 内存分配失败时未回滚已分配的内存

当某一行的 malloc 失败时,你只释放了当前失败的指针,而之前已经成功分配的行内存以及 arr 本身都没有释放,直接返回 NULL,这些已分配的内存就变成了泄漏。

修复后的代码

修复后的 allocate_array 函数

//! allocate an m x n fully-dynamic 2D array
int** allocate_array (int m, int n)
{
    int ** arr = malloc (sizeof(int *) * m);
    if (!arr)
    {
        return NULL; // malloc失败直接返回,这里arr是NULL,不需要free
    }
    
    for (int i = 0; i < m; i++) // 循环m次,对应m行
    {
        arr[i] = malloc (sizeof(int) * n);
        if (!arr[i])
        {
            // 回滚:释放之前已分配的所有行
            for (int j = 0; j < i; j++)
            {
                free(arr[j]);
                arr[j] = NULL;
            }
            free(arr); // 释放行指针数组
            arr = NULL;
            return NULL;
        }
    }
    
    return arr;
}

其他函数的小修正(非内存泄漏,但符合输出要求)

print_array 函数会导致每行末尾多一个空格,调整后让最后一个元素不输出空格:

//! print an m x n fully-dynamic array
//! use one line per row, 2 digits per integer ("%2d"), one space
void print_array (int **array, int m, int n)
{
    for (int i = 0; i < m; i++)
    {
        for (int j = 0; j < n; j++)
        {
            if (j == 0)
                printf("%2d", array[i][j]);
            else
                printf(" %2d", array[i][j]);
        }
        printf("\n");
    }
}

free_and_nullify_array 函数本身逻辑是正确的,不需要修改。

验证说明

修复后,测试用例的执行逻辑:

  1. 成功分配2行3列的动态二维数组
  2. 赋值后打印输出符合预期(无末尾空格)
  3. 释放所有行内存和行指针数组,最终array被置为NULL
  4. 内存泄漏检测工具(如Valgrind)会显示无泄漏

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 11:34:52