问题描述
我的小C程序正在遍历工作目录的内容,这没有问题,但是我用Valgrind进行了检查,发现有些神秘的泄漏我无法消失几天。
下面是代码:
struct record {
char* fullPath;
int wdlen; // working directory length
int relplen; // relative path length
int namlen; // name length
bool folder; // is folder
long modified;
};
void populateDB() {
struct record** records = NULL;
int entryCount = 0;
bool error = false;
listDirRecursive(workingDirectory,&entryCount,&records,&error);
if (error) {
goto cleanup;
}
for (int i = 0; i < entryCount; i++) {
printfColor(C_MAGENTA,"%d. wdlen: %d,\t\trelPathLen: %d,\t\tnamelen: %d,\t\tfolder: %s,\t\tmod: %ld,\t\tpath: %s\n",i,records[i]->wdlen,records[i]->relplen,records[i]->namlen,records[i]->folder ? "true" : "false",records[i]->modified,records[i]->fullPath);
}
// initDatabase(&entryCount,&records);
cleanup:
for (int i = 0; i < entryCount; i++) {
free(records[i]->fullPath);
free(records[i]);
}
free(records);
}
void listDirRecursive(const char* path,int* count,struct record*** records,bool* error) {
if (*error) return;
struct dirent** fileList = NULL;
int fileCount = scandir(path,&fileList,NULL,alphasort);
if (fileCount < 0) {
printfColor(C_RED,"Couldn't open: %s\n",path);
*error = true;
return;
}
struct record** tmpRecords = malloc(fileCount * sizeof *tmpRecords);
if (!tmpRecords) {
printfColor(C_RED,"Couldn't allocate memory for records\n");
*error = true;
return;
}
struct record* act = NULL;
struct stat filestat;
int processedFiles = 0;
for (int i = 0,wdlen = strlen(workingDirectory),plen = strlen(path); i < fileCount; i++) {
if (strcmp(fileList[i]->d_name,".") == 0 ||
strcmp(fileList[i]->d_name,"..") == 0) continue;
act = malloc(sizeof *act);
if (!act) {
printfColor(C_RED,"Couldn't allocate memory for actual record\n");
*error = true;
goto cleanup;
}
act->fullPath = malloc(plen + fileList[i]->d_namlen + 2);
if (!act->fullPath) {
printfColor(C_RED,"Couldn't allocate memory for actual record's full path\n");
*error = true;
goto cleanup;
}
strcat(strcat(strcpy(act->fullPath,path),"/"),fileList[i]->d_name);
act->wdlen = wdlen + 1;
act->relplen = strlen(act->fullPath) - ((wdlen + 1) + fileList[i]->d_namlen);
act->namlen = fileList[i]->d_namlen;
act->folder = fileList[i]->d_type == DT_DIR;
stat(act->fullPath,&filestat);
act->modified = filestat.st_mtimespec.tv_nsec;
tmpRecords[processedFiles++] = act;
if (fileList[i]->d_type == DT_DIR) {
char* p = malloc(plen + fileList[i]->d_namlen + 2);
strcat(strcat(strcpy(p,fileList[i]->d_name);
listDirRecursive(p,count,records,error);
free(p);
}
}
if (processedFiles == 0) {
goto cleanup;
}
struct record** shrinkedTmpRecords = realloc(tmpRecords,processedFiles * sizeof *shrinkedTmpRecords);
if (!shrinkedTmpRecords) {
if (verbose) printf("Shrinking tmpRecords failed. Some memory leak will happen\n");
}
else {
tmpRecords = shrinkedTmpRecords;
}
int newCount = *count + processedFiles;
if (*count == 0) {
*records = tmpRecords;
}
else {
struct record** newRecords = realloc(*records,newCount * sizeof *newRecords);
if (!newRecords) {
printfColor(C_RED,"Couldn't allocate memory for further records\n");
*error = true;
goto cleanup;
}
*records = newRecords;
for (int i = 0,j = *count; i < processedFiles; i++,j++) {
(*records)[j] = tmpRecords[i];
}
}
*count = newCount;
cleanup:
for (int i = 0; i < fileCount; i++) {
free(fileList[i]);
}
free(fileList);
}
运行后,Valgrind的输出为:
==40861== HEAP SUMMARY:
==40861== in use at exit: 18,084 bytes in 170 blocks
==40861== total heap usage: 423 allocs,253 frees,180,357 bytes allocated
==40861==
==40861== 8 bytes in 1 blocks are definitely lost in loss record 1 of 43
==40861== at 0x100111FD6: realloc (in /usr/local/Cellar/valgrind/HEAD-e0af3eb/lib/valgrind/vgpreload_memcheck-amd64-darwin.so)
==40861== by 0x10000162B: listDirRecursive (filesystem.c:137)
==40861== by 0x1000015DA: listDirRecursive (filesystem.c:127)
==40861== by 0x1000015DA: listDirRecursive (filesystem.c:127)
==40861== by 0x1000015DA: listDirRecursive (filesystem.c:127)
==40861== by 0x1000015DA: listDirRecursive (filesystem.c:127)
==40861== by 0x100001092: populateDB (filesystem.c:44)
==40861== by 0x100000E15: init (mtl.c:111)
==40861== by 0x100000CD2: main (mtl.c:61)
==40861==
==40861== 16 bytes in 2 blocks are definitely lost in loss record 5 of 43
==40861== at 0x100111FD6: realloc (in /usr/local/Cellar/valgrind/HEAD-e0af3eb/lib/valgrind/vgpreload_memcheck-amd64-darwin.so)
==40861== by 0x10000162B: listDirRecursive (filesystem.c:137)
==40861== by 0x1000015DA: listDirRecursive (filesystem.c:127)
==40861== by 0x1000015DA: listDirRecursive (filesystem.c:127)
==40861== by 0x1000015DA: listDirRecursive (filesystem.c:127)
==40861== by 0x100001092: populateDB (filesystem.c:44)
==40861== by 0x100000E15: init (mtl.c:111)
==40861== by 0x100000CD2: main (mtl.c:61)
==40861==
==40861== 72 bytes in 5 blocks are definitely lost in loss record 22 of 43
==40861== at 0x100111FD6: realloc (in /usr/local/Cellar/valgrind/HEAD-e0af3eb/lib/valgrind/vgpreload_memcheck-amd64-darwin.so)
==40861== by 0x10000162B: listDirRecursive (filesystem.c:137)
==40861== by 0x1000015DA: listDirRecursive (filesystem.c:127)
==40861== by 0x1000015DA: listDirRecursive (filesystem.c:127)
==40861== by 0x100001092: populateDB (filesystem.c:44)
==40861== by 0x100000E15: init (mtl.c:111)
==40861== by 0x100000CD2: main (mtl.c:61)
==40861==
==40861== 80 bytes in 1 blocks are definitely lost in loss record 23 of 43
==40861== at 0x100111FD6: realloc (in /usr/local/Cellar/valgrind/HEAD-e0af3eb/lib/valgrind/vgpreload_memcheck-amd64-darwin.so)
==40861== by 0x10000162B: listDirRecursive (filesystem.c:137)
==40861== by 0x100001092: populateDB (filesystem.c:44)
==40861== by 0x100000E15: init (mtl.c:111)
==40861== by 0x100000CD2: main (mtl.c:61)
==40861==
==40861== 112 bytes in 4 blocks are definitely lost in loss record 26 of 43
==40861== at 0x100111FD6: realloc (in /usr/local/Cellar/valgrind/HEAD-e0af3eb/lib/valgrind/vgpreload_memcheck-amd64-darwin.so)
==40861== by 0x10000162B: listDirRecursive (filesystem.c:137)
==40861== by 0x1000015DA: listDirRecursive (filesystem.c:127)
==40861== by 0x100001092: populateDB (filesystem.c:44)
==40861== by 0x100000E15: init (mtl.c:111)
==40861== by 0x100000CD2: main (mtl.c:61)
==40861==
==40861== LEAK SUMMARY:
==40861== definitely lost: 288 bytes in 13 blocks
==40861== indirectly lost: 0 bytes in 0 blocks
==40861== possibly lost: 0 bytes in 0 blocks
==40861== still reachable: 0 bytes in 0 blocks
==40861== suppressed: 17,796 bytes in 157 blocks
288字节除以8(指针的大小)为36,这是末尾的总记录(文件和文件夹)。 13块计数等于文件夹数。
我尝试了所有想到的方法,但没有任何效果,我正在学习C语言,因此很可能我不了解一些必不可少的内容(我在该主题中读了很多,并试图避免过分的否定)。
如果有人不了解printfColor
是什么,那就是:
// header file:
enum Color {
C_RED,C_BOLD_RED,C_GREEN,C_BOLD_GREEN,C_YELLOW,C_BOLD_YELLOW,C_BLUE,C_BOLD_BLUE,C_MAGENTA,C_BOLD_MAGENTA,C_CYAN,C_BOLD_CYAN,C_RESET
};
static const char* colors[] = {
"\033[0;31m",// RED
"\033[1;31m",// BOLD RED
"\033[0;32m",// GREEN
"\033[1;32m",// BOLD GREEN
"\033[0;33m",// YELLOW
"\033[01;33m",// BOLD YELLOW
"\033[0;34m",// BLUE
"\033[1;34m",// BOLD BLUE
"\033[0;35m",// MAGENTA
"\033[1;35m",// BOLD MAGENTA
"\033[0;36m",// CYAN
"\033[1;36m",// BOLD CYAN
"\033[0m" // RESET
};
// c file:
void printfColor(enum Color color,const char* format,...) {
va_list args;
printf("%s",colors[color]);
va_start(args,format);
vprintf(format,args);
va_end(args);
printf("%s",colors[C_RESET]);
}
Chears
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)