C语言递归函数free()使用问题:目录遍历代码内存泄漏排查
内存泄漏问题分析与修复方案
嘿,我帮你定位到内存泄漏的原因了——你必须要释放depthPath,而且问题正好出在你没处理.和..这两个特殊目录项的内存分配上!
为什么会泄漏?
看你代码里的这段逻辑:
depthPath= (char*)malloc(strlen(path) + strlen(dir->d_name) + 1); strcpy(depthPath, path); strcat(depthPath, "/"); strcat(depthPath, dir->d_name); if(((strcmp(dir->d_name,".")!=0) && (strcmp(dir->d_name,".."))!=0) ){ recursiveFoo(depthPath); free(depthPath); }
每次进入循环,你都会先调用malloc为depthPath分配内存,但只有当当前目录项不是.或..的时候,才会执行free(depthPath)。如果遇到.或者..,你只完成了内存分配,却直接跳过了释放步骤,这就是Valgrind报告的2块内存泄漏的根源。
怎么修复?
核心原则是:每一次malloc都必须对应一次free,不管当前目录项是不是特殊目录。你只需要把free(depthPath)移到if语句外面,确保每次分配的内存都会被释放:
修改后的完整recursiveFoo函数:
void recursiveFoo (char *path){ char *depthPath; DIR *d; struct dirent *dir; d = opendir(path); if (d) { while ((dir = readdir(d)) != NULL) { // 注意:这里要+2,因为需要给'/'和字符串结束符'\0'各留一个位置,原来的+1不够! depthPath= (char*)malloc(strlen(path) + strlen(dir->d_name) + 2); strcpy(depthPath, path); strcat(depthPath, "/"); strcat(depthPath, dir->d_name); if(((strcmp(dir->d_name,".")!=0) && (strcmp(dir->d_name,"..")!=0)) ){ recursiveFoo(depthPath); } // 不管是不是特殊目录,都要释放内存 free(depthPath); } printf("%s/",path ); closedir(d); } }
另外还要提醒你一个隐藏的问题:你原来的malloc大小计算错误!strlen(path) + strlen(dir->d_name) + 1没有算上拼接的"/"的长度,应该是+2(1个字符给/,1个给字符串结束符\0),否则strcat(depthPath, "/")会导致内存越界,引发未定义行为。
修复后验证
修改完代码,用-ggdb3重新编译,再跑Valgrind,应该会看到类似这样的输出,说明没有内存泄漏了:
==XXXX== HEAP SUMMARY: ==XXXX== in use at exit: 0 bytes in 0 blocks ==XXXX== total heap usage: X allocs, X frees, X bytes allocated ==XXXX== ==XXXX== LEAK SUMMARY: ==XXXX== definitely lost: 0 bytes in 0 blocks ==XXXX== indirectly lost: 0 bytes in 0 blocks ==XXXX== possibly lost: 0 bytes in 0 blocks ==XXXX== still reachable: 0 bytes in 0 blocks ==XXXX== suppressed: 0 bytes in 0 blocks ==XXXX== ==XXXX== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
内容的提问来源于stack exchange,提问作者javac
相关产品推荐
相关产品推荐

