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

C程序输出正常但Valgrind检测到内存泄漏问题排查

CSV读取程序内存泄漏排查与修复

泄漏原因

从Valgrind输出和代码逻辑来看,泄漏的5字节来自CSV文件的表头行处理:

  1. 程序读取第一行表头name,id,balance时,先通过malloc(len+1)为customer.name分配了5字节内存(存储字符串"name")。
  2. 后续执行sscanf(tmp,"%d",&customer.id)时,因为表头的id是字符串而非整数,转换失败,触发continue直接进入下一次循环。
  3. customer是循环内的栈变量,循环结束后其地址失效,而customer.name指向的堆内存没有被释放,导致这5字节内存永久丢失。

此外,代码中其他触发continue的分支(如balance转换失败)也存在相同的潜在泄漏风险,只要已经分配了customer.name但未将结构体存入数组,就会丢失内存。

修复方案

在所有可能触发continue的分支前,先释放已分配的customer.name内存;同时修正程序退出状态(原本末尾错误使用EXIT_FAILURE)。

修改后的关键代码片段

/* MINIMAL conversion validation with sscanf() */
if(sscanf(tmp,"%d",&customer.id) != 1){
    fprintf(stderr,"error: invalid integer value for line[%d]\n",index+1);
    free(customer.name); // 释放已分配的name内存
    continue;
}

if(!(tmp = strtok(NULL,delim))){
    fprintf(stderr,"\nerror: strtok()-balance should have more line\n");
    free(customer.name); // 释放已分配的name内存
    continue;
}

if(sscanf(tmp,"%lf", &customer.balance) != 1){
    fprintf(stderr,"error: invalid float value for line[%d]\n", index+1);
    free(customer.name); // 释放已分配的name内存
    continue;
}

完整修复后的main函数末尾修正

将末尾的exit(EXIT_FAILURE);改为:

exit(EXIT_SUCCESS);

验证结果

重新编译并使用Valgrind检测:

valgrind -s --leak-check=full ./a.out dat/test.csv

输出中将显示HEAP SUMMARY里in use at exit: 0 bytes in 0 blocks,泄漏问题完全解决。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 07:15:35