警告:files[counter].name=path 保存了一个局部变量地址,并且在每次循环中你都会修改它,所以所有的名字都是一样的,你需要保存一个副本(strdup)
对于 listFilesRecursively 的每次调用,您在堆栈中使用超过 1000 个字节,最好不要在堆栈中使用该字符串并直接使用在堆中分配的路径
我没有看到将 files 和 counters 作为局部变量的兴趣,你把它们弄丢了
提案
#include <stdio.h>
#include <dirent.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#define NFILES 100;
typedef struct file {
char * name;
struct stat file_info;
} file;
void listFilesRecursively(char *basePath, file ** files, int * size, int * index)
{
DIR *dir = opendir(basePath);
if (!dir)
return;
struct dirent *dp;
struct stat buf;
while ((dp = readdir(dir)) != NULL)
{
if ((strcmp(dp->d_name, ".") != 0) && (strcmp(dp->d_name, "..") != 0))
{
size_t sz = strlen(basePath);
char * pathname = malloc(sz + strlen(dp->d_name) + 2);
if (pathname == NULL) {
/* out of memory */
closedir(dir);
return;
}
strcpy(pathname, basePath);
pathname[sz] = '/';
strcpy(pathname + sz + 1, dp->d_name);
stat(pathname, &buf);
if (S_ISDIR(buf.st_mode)) {
/* suppose dirs not memorized */
listFilesRecursively(pathname, files, size, index);
free(pathname);
}
else if (S_ISREG(buf.st_mode)) {
/* a file, memorize it */
if (++*index == *size) {
*size += NFILES;
*files = realloc(*files, (*size) * sizeof(file));
}
(*files)[*index].file_info = buf;
(*files)[*index].name = pathname;
}
else
/* bypassed */
free(pathname);
}
}
closedir(dir);
}
int compPathname(const void * a, const void * b)
{
return strcmp(((file *) a)->name, ((file *) b)->name);
}
int main()
{
int size = NFILES;
int index = -1;
file * files = malloc(size * sizeof(file));
listFilesRecursively(".", &files, &size, &index);
if (index != -1) {
qsort(files, index + 1, sizeof(file), compPathname);
/* write and free memory */
for (int i = 0; i <= index; ++i) {
printf("%s : %ld\n", files[i].name, (long) files[i].file_info.st_size);
free(files[i].name);
}
}
free(files);
return 0;
}
我只记住常规文件的路径名和大小,不保存目录和动态链接等
我按路径名排序
每次文件太小我都加NFILES,NFILES可以是任意数字>0
在 valgrind 下执行:
==9329== Memcheck, a memory error detector
==9329== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==9329== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==9329== Command: ./a.out
==9329==
./.X0-lock : 11
./a.out : 12920
./f.c : 2485
./vgdb-pipe-shared-mem-vgdb-9329-by-pi-on-??? : 36
==9329==
==9329== HEAP SUMMARY:
==9329== in use at exit: 0 bytes in 0 blocks
==9329== total heap usage: 35 allocs, 35 frees, 339,242 bytes allocated
==9329==
==9329== All heap blocks were freed -- no leaks are possible
==9329==
==9329== For counts of detected and suppressed errors, rerun with: -v
==9329== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 6 from 3)