c - 在C中的递归函数中使用free()函数

标签 c recursion

我有一个基本的递归函数来遍历目录。

代码中存在一些内存泄漏。但我找不到它们,我尝试过free()在某些行中,但是它不起作用。

有 6 个分配项和 4 个空闲项。我怎样才能使它 6 个分配和 6 个空闲?我想我应该free depthPath ,我不应该吗? (如果是,我应该在哪里free它?)

这是我的 C 程序:

#include <stdio.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <string.h>
#include <dirent.h> 

void recursiveFoo (char *path);

int main(int argc, char **argv){

    recursiveFoo (argv[1]);

    return 0; 
}

void recursiveFoo (char *path){
    char *depthPath;
    DIR *d;
    struct dirent *dir;
    d = opendir(path);
    if (d) {
        while ((dir = readdir(d)) != NULL) {   

            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); 
            }

        }

        printf("%s/",path );

        closedir(d);
    }
}

编译后-ggdb3 ,这是我的 Valgrind 输出:

   ==641== HEAP SUMMARY:
==641==     in use at exit: 13 bytes in 2 blocks
==641==   total heap usage: 6 allocs, 4 frees, 33,876 bytes allocated
==641== 
==641== Searching for pointers to 2 not-freed blocks
==641== Checked 62,760 bytes
==641== 
==641== 13 bytes in 2 blocks are definitely lost in loss record 1 of 1
==641==    at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==641==    by 0x400839: recursiveFoo (stack.c:29)
==641==    by 0x4007D7: main (stack.c:14)
==641== 
==641== LEAK SUMMARY:
==641==    definitely lost: 13 bytes in 2 blocks
==641==    indirectly lost: 0 bytes in 0 blocks
==641==      possibly lost: 0 bytes in 0 blocks
==641==    still reachable: 0 bytes in 0 blocks
==641==         suppressed: 0 bytes in 0 blocks
==641== 
==641== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
==641== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)

最佳答案

此代码没有为复制到 block 中的字符串分配足够的内存:

        depthPath= (char*)malloc(strlen(path) + strlen(dir->d_name) + 1);
        strcpy(depthPath, path);
        strcat(depthPath, "/");
        strcat(depthPath, dir->d_name);

新字符串需要 strlen(path) + strlen(dir->d_name) + strlen( "/") + 1 个字符来同时包含 "/" 终止'\0'

此外,为了修复您的泄漏,此代码

    while ((dir = readdir(d)) != NULL) {   

        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);   
        }

    }

可以写成

    while ((dir = readdir(d)) != NULL)
    {   
        if(((strcmp(dir->d_name,".")==0) ||
            (strcmp(dir->d_name,".."))==0) )
        {
            continue;
        }

        char *depthPath= malloc(strlen(path) + strlen(dir->d_name) + 2);
        strcpy(depthPath, path);
        strcat(depthPath, "/");
        strcat(depthPath, dir->d_name);

        recursiveFoo(depthPath);   

        free(depthPath):
    }

关于c - 在C中的递归函数中使用free()函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55072006/

相关文章:

php - 将嵌套数组转换为嵌套 html block 的递归 php 函数

c++ - 从源文件添加编译时消息

c - SQLite 使用 C 文件添加功能

c++ - 如何清除c中的内存

recursion - erlang 如何处理混合尾递归的 case 语句

haskell - 为什么这是一个非详尽的搜索模式?

将 const char* 复制到 c 中的字符串

c - 如何观察一个变量?

c# - 三位数字的递归排列

list - 递归如何满足基本情况 Haskell