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

使用Valgrind检测C语言动态数组出现内存泄漏的原因排查

动态数组内存泄漏原因分析

问题描述

编写自定义动态数组后,自认为内存管理逻辑正确,但Valgrind检测出明确的内存泄漏,需定位问题根源。

泄漏根源分析

问题核心出在realloc_array函数的实现上:

void realloc_array(array* arr, int size)
{
    int* new_arr = (int*)malloc(size * sizeof(int));
    memcpy((void*)new_arr, arr->arr, arr->size * sizeof(int));
    arr->arr = new_arr;
}

每次调用该函数时,都会通过malloc分配新内存块并完成数据拷贝,但完全没有释放旧的arr->arr指向的内存。

结合代码执行流程来看:

  1. 初始创建数组时,create_array分配了20字节的内存(5个int,按4字节/int计算);
  2. 添加第6个元素时触发第一次扩容,realloc_array分配28字节新内存(7个int),但原20字节内存的指针被新地址覆盖,这块内存从此无法被访问和释放;
  3. 添加第8个元素时触发第二次扩容,再次分配40字节新内存(10个int),同样未释放之前的28字节内存;
  4. 最终delete_array仅释放了最后一次分配的40字节内存和数组结构体本身,之前的20字节、28字节内存彻底丢失,对应Valgrind检测到的两个泄漏块。

Valgrind的检测结果也直接指向这两处:

  • 20字节泄漏来自create_array中初始分配的数组内存;
  • 28字节泄漏来自第一次扩容时realloc_array分配的内存块。

修复方法

修改realloc_array函数,在替换指针前释放旧内存:

void realloc_array(array* arr, int size)
{
    int* new_arr = (int*)malloc(size * sizeof(int));
    memcpy((void*)new_arr, arr->arr, arr->size * sizeof(int));
    free(arr->arr); // 释放旧内存块
    arr->arr = new_arr;
}

也可以直接使用标准库的realloc函数简化实现,它会自动处理旧内存的释放(分配成功时):

void realloc_array(array* arr, int size)
{
    int* new_arr = (int*)realloc(arr->arr, size * sizeof(int));
    if (new_arr != NULL) { // 必须检查realloc是否成功
        arr->arr = new_arr;
    }
    // 可添加分配失败的错误处理逻辑
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 20:35:06