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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.13 06:31:26