gpt4 book ai didi

c - 自由函数在c中不自由

转载 作者:行者123 更新时间:2023-11-30 19:38:59 25 4
gpt4 key购买 nike

我的代码中的所有内容都工作正常,除了 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 库

最佳答案

看来我看错了代码;没有内存泄漏,但存在 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() 接口(interface)(也已重命名)以及所使用的简单实现。我测试代码的一个目录中有超过 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 仅要求 struct dirent 结构中的 d_named_ino,因此我使用了 strlen(ent->d_name)确定名称长度。您可以自行决定该级别的可移植性对您是否重要 - 大多数系统可能确实提供d_namlen。请注意,openDirectory() 函数现在报告它放入数组中的文件数量,并告知它有多少可用空间。

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

关于c - 自由函数在c中不自由,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37283994/

25 4 0
文章推荐: c - 类型 "char (*)[16]"的参数与类型 "const char *"的参数不兼容
文章推荐: c# - 从 List 获取对象,其中属性为 null 且顺序为最低