我的代码中的所有内容都能正常运行,但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库
答案 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_ino
和struct dirent
,因此我使用strlen(ent->d_name)
来确定名称长度。您可以自己决定这种可移植性是否对您很重要 - 大多数系统可能提供d_namlen
。请注意,openDirectory()
函数现在报告它放入数组的文件数量,并告知它可以使用多少空间。
预先分配字符串实际上主要是浪费精力。如果是我的代码,我只需使用calloc()
作为(nulled)指针数组,然后使用strdup()
复制名称。而且我可能会根据需要动态增长指针数组。