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

请问如下动态分配内存的二维数组释放代码存在什么错误?如何修复?

动态二维数组内存释放逻辑分析

现有代码可取之处

释放顺序符合规范:先逐行释放每一行的一维数组内存,再释放存储行指针的二级指针内存,遵循了「后申请先释放」的动态内存管理原则,不存在释放顺序颠倒导致的野指针问题。

存在的问题及修复方案

问题1:行内存分配失败时存在内存泄漏

对应问题代码段:

if (NULL == *(pptr + idx)) {
    printf("ERROR: malloc failed.\n");
    exit(1);
}
  • 错误原因:如果循环到第N行时malloc失败,程序直接退出,前面0~N-1行已经分配成功的内存、以及最开始申请的二级指针pptr指向的8个int*大小的内存都没有被释放,产生内存泄漏。
  • 修复方案:分配失败时,先释放已经申请成功的所有行内存,再释放二级指针pptr,再退出程序,修改后的分配逻辑如下:
for (idx = 0; idx < 8; idx++) {
    *(pptr + idx) = (int*)malloc(sizeof(int) * 6);
    if (NULL == *(pptr + idx)) {
        printf("ERROR: malloc failed.\n");
        // 先释放已分配的行内存
        for(int j = 0; j < idx; j++) {
            free(*(pptr + j));
        }
        free(pptr); // 释放二级指针内存
        exit(1);
    }
}

问题2:free后判断指针非空再置空的逻辑错误

对应问题代码段:

free(*(pptr + idx));
if (NULL != *(pptr + idx)) {
    *(pptr + idx) = NULL;
}
...
free(pptr);
if (NULL != pptr) {
    pptr = NULL;
}
  • 错误原因:C标准中free()函数只会回收指针指向的堆内存,不会修改指针变量本身的取值,调用free后指针仍然指向原来的内存地址(变为野指针),因此NULL != *(pptr + idx)的判断永远为真,属于完全冗余的无效逻辑。
  • 修复方案:删除冗余的非空判断,free后直接将指针置为NULL即可,修改后的释放逻辑如下:
for (idx = 0; idx < 8; idx++) {
    free(*(pptr + idx));
    *(pptr + idx) = NULL;
}
free(pptr);
pptr = NULL;

可选优化建议

C语言中不需要强制转换malloc的返回值,void*可以自动隐式转换为任意指针类型,强制转换反而可能隐藏未引入<stdlib.h>的编译警告。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 11:24:02