C程序输出正常但Valgrind检测到内存泄漏问题排查
CSV读取程序内存泄漏排查与修复
泄漏原因
从Valgrind输出和代码逻辑来看,泄漏的5字节来自CSV文件的表头行处理:
- 程序读取第一行表头
name,id,balance时,先通过malloc(len+1)为customer.name分配了5字节内存(存储字符串"name")。 - 后续执行
sscanf(tmp,"%d",&customer.id)时,因为表头的id是字符串而非整数,转换失败,触发continue直接进入下一次循环。 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
相关产品推荐
相关产品推荐

