免费功能在c中没有空闲

时间:2016-05-17 18:43:43

标签: c

我的代码中的所有内容都能正常运行,但freeFunc函数正在停止运行,我不知道为什么。

void orderTheFiles(char* path)
{
    int i = 0;
    DIR * dir = opendir(path);
    DIR * exampleDir = opendir(path);
    int length = checkHowMuchFiles(exampleDir);
    if (length != EXIT)
    {
        char** arr = (char**)calloc(length,sizeof(char*));
        dynamicFunc(arr, length);
        openDirectory(dir, arr);
        freeFunc(arr, length);
    }

}

checkHowMuchFiles功能并不重要,但它确实有效。

这里是dynamicFunc:

void dynamicFunc(char** arr, int length)
{
    int i = 0;
    for (; i < length; i++)
    {
        arr[i] = calloc(MAX_LENGTH_OF_STRING,sizeof(char));
    }
}

我尝试使用此函数打开目录,并将整个文件名放在动态数组中,并按字符串长度重新分配数组:

int openDirectory(DIR * dir, char** arr)
{
    int flag = 0;
    int i = 0;
    struct dirent *ent;
    if ((dir== NULL))
    {
        printf("Sorry can't open the directory\n");
        flag = 1;
    }
    else
    {
        while (i < NUMBER_OF_GRABADGE_FILES)
        {
            readdir(dir); //This line deletes our garbage files like '.' and '..' (maybe it's just on my computer)
            i++;
        }
        i = 0;
        while ((ent = readdir(dir)) != NULL)
        {
            arr[i] = realloc(arr[i], (sizeof(char)*ent->d_namlen) + 1);
            strncpy(arr[i], ent->d_name, MAX_LENGTH_OF_STRING);
            printf("%s\n", arr[i]);
            i++;
        }

    }
    closedir(dir);
    return flag;
}

免费功能:

void freeFunc(char** arr, int length)
{
    int i = 0;
    for (; i < length; i++)
    {
        free(arr[i]);
    }
    free(arr);
}

注意:我使用了dirent.h库

1 个答案:

答案 0 :(得分:0)

看起来我误读了代码;没有内存泄漏,但有BLUEPIXY noted

的问题

这是我的经过消毒,完成,测试,valgrind - 干净的代码:

#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <dirent.h>
#include <string.h>

enum { MAX_LENGTH_OF_STRING = 256 };

static int checkHowManyFiles(const char *path)
{
    assert(path != 0);
    return 100;
}

static void oom(void)
{
    fprintf(stderr, "Out of memory!\n");
    exit(EXIT_FAILURE);
}

static void dynamicFunc(char** arr, int length)
{
    int i = 0;
    for (; i < length; i++)
    {
        if ((arr[i] = calloc(MAX_LENGTH_OF_STRING,sizeof(char))) == 0)
            oom();
    }
}

enum { NUMBER_OF_GRABADGE_FILES = 2 };

static int openDirectory(DIR * dir, char** arr, int num_files)
{
    int flag = 0;
    int i = 0;
    struct dirent *ent;
    if ((dir== NULL))
    {
        printf("Sorry can't open the directory\n");
        flag = -1;
    }
    else
    {
        /* Skip . and .. */
        for (i = 0; i < NUMBER_OF_GRABADGE_FILES; i++)
        {
            if (readdir(dir) == 0)
                break;
        }
        for (i = 0; i < num_files && (ent = readdir(dir)) != NULL; i++)
        {
            /* d_namlen is not mandated by POSIX (only d_name, d_ino are) */
            size_t namlen = strlen(ent->d_name) + 1;
            arr[i] = realloc(arr[i], namlen);
            if (arr[i] == 0)
                oom();
            strncpy(arr[i], ent->d_name, namlen);
            printf("%d [%s]\n", i, arr[i]);
        }
        flag = i;
    }
    closedir(dir);
    return flag;
}

static void freeFunc(char** arr, int length)
{
    int i = 0;
    for (; i < length; i++)
    {
        free(arr[i]);
    }
    free(arr);
}

static void orderTheFiles(char* path)
{
    DIR * dir = opendir(path);
    int length = checkHowManyFiles(path);
    printf("Will assume there are no more than %d files\n", length);
    if (length > 0)
    {
        char** arr = (char**)calloc(length,sizeof(char*));
        dynamicFunc(arr, length);
        int n = openDirectory(dir, arr, length);
        printf("Actually got %d files\n", n);
        freeFunc(arr, length);
    }
    else
        closedir(dir);
}

int main(void)
{
    orderTheFiles(".");
    return 0;
}

请注意修改后的checkHowManyFiles()接口 - 它也被重命名 - 并且使用了简单的实现。在我测试代码的其中一个目录中有超过100个文件,而在另一个目录中只有5个。

$ ../di19
==3546== Memcheck, a memory error detector
==3546== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==3546== Using Valgrind-3.12.0.SVN and LibVEX; rerun with -h for copyright info
==3546== Command: ../di19
==3546== 
Will assume there are no more than 100 files
0 [aes]
1 [aes.c]
2 [aes.dSYM]
3 [aes.h]
4 [makefile]
Actually got 5 files
==3546== 
==3546== HEAP SUMMARY:
==3546==     in use at exit: 26,329 bytes in 187 blocks
==3546==   total heap usage: 380 allocs, 193 frees, 63,291 bytes allocated
==3546== 
==3546== LEAK SUMMARY:
==3546==    definitely lost: 0 bytes in 0 blocks
==3546==    indirectly lost: 0 bytes in 0 blocks
==3546==      possibly lost: 0 bytes in 0 blocks
==3546==    still reachable: 0 bytes in 0 blocks
==3546==         suppressed: 26,329 bytes in 187 blocks
==3546== 
==3546== For counts of detected and suppressed errors, rerun with: -v
==3546== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
$

现在代码确保它不会超出界限。由于POSIX仅在d_name结构中强制要求d_inostruct dirent,因此我使用strlen(ent->d_name)来确定名称长度。您可以自己决定这种可移植性是否对您很重要 - 大多数系统可能提供d_namlen。请注意,openDirectory()函数现在报告它放入数组的文件数量,并告知它可以使用多少空间。

预先分配字符串实际上主要是浪费精力。如果是我的代码,我只需使用calloc()作为(nulled)指针数组,然后使用strdup()复制名称。而且我可能会根据需要动态增长指针数组。