使用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指向的内存。
结合代码执行流程来看:
- 初始创建数组时,
create_array分配了20字节的内存(5个int,按4字节/int计算); - 添加第6个元素时触发第一次扩容,
realloc_array分配28字节新内存(7个int),但原20字节内存的指针被新地址覆盖,这块内存从此无法被访问和释放; - 添加第8个元素时触发第二次扩容,再次分配40字节新内存(10个
int),同样未释放之前的28字节内存; - 最终
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
相关产品推荐
相关产品推荐

