fork() 导致内存泄漏
fork() is causing memory leak
当我尝试递归遍历 fork.Fork 中的目录时导致内存泄漏。每个 directory.But valgrind 都说 opendir_tail.I 尝试在父级中写入 clodir 但后来我分配了 1 个但 2 个空闲 error.Where 是问题吗?
这是我的代码。
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <fcntl.h>
#include <string.h>
#include <sys/stat.h>
#include <dirent.h>
#include <errno.h>
#include <ctype.h>
int dfsdirectory (char *path){
DIR* dir;
struct dirent *dirEntry;
struct stat fileStat;
char _PathN[1000];
int totalSize=0;
if (!(dir = opendir(path))){
closedir(dir);
return -1;
}
while ( ((dirEntry=readdir(dir)) != 0) ) {
int dirSize=0;
if (strcmp(dirEntry->d_name, ".") == 0
|| strcmp(dirEntry->d_name, "..") == 0)
continue;
snprintf(_PathN, sizeof(_PathN), "%s/%s", path, dirEntry->d_name);
lstat (_PathN, &fileStat);
if (S_ISDIR(fileStat.st_mode)){
int PID = fork();
if(PID<0){
closedir(dir);
return -1;
}
if(PID == 0){
dfsdirectory(_PathN);
while ((closedir(dir) == -1) && (errno == EINTR));
exit(0);
}
else{
wait(NULL);
}
}
}
closedir(dir);
return totalSize;
}
int main() {
dfsdirectory("A");
}
和 valgrind 输出
==4070== Memcheck, a memory error detector
==4070== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==4070== Using Valgrind-3.12.0.SVN and LibVEX; rerun with -h for copyright
info
==4070== Command: ./main
==4070== Parent PID: 953
==4070==
==4072==
==4072== HEAP SUMMARY:
==4072== in use at exit: 32,816 bytes in 1 blocks
==4072== total heap usage: 3 allocs, 2 frees, 98,448 bytes allocated
==4072==
==4072== 32,816 bytes in 1 blocks are still reachable in loss record 1 of 1
==4072== at 0x4C2BBAF: malloc (vg_replace_malloc.c:299)
==4072== by 0x4EEB813: __alloc_dir (opendir.c:247)
==4072== by 0x4EEB902: opendir_tail (opendir.c:145)
==4072== by 0x108977: dfsdirectory (in /home/alex/Desktop/main)
==4072== by 0x108AE6: main (in /home/alex/Desktop/main)
==4072==
==4072== LEAK SUMMARY:
==4072== definitely lost: 0 bytes in 0 blocks
==4072== indirectly lost: 0 bytes in 0 blocks
==4072== possibly lost: 0 bytes in 0 blocks
==4072== still reachable: 32,816 bytes in 1 blocks
==4072== suppressed: 0 bytes in 0 blocks
==4072==
==4072== For counts of detected and suppressed errors, rerun with: -v
==4072== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
==4071==
==4071== HEAP SUMMARY:
==4071== in use at exit: 0 bytes in 0 blocks
==4071== total heap usage: 2 allocs, 2 frees, 65,632 bytes allocated
==4071==
==4071== All heap blocks were freed -- no leaks are possible
==4071==
==4071== For counts of detected and suppressed errors, rerun with: -v
==4071== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
==4075==
==4075== HEAP SUMMARY:
==4075== in use at exit: 65,632 bytes in 2 blocks
==4075== total heap usage: 4 allocs, 2 frees, 131,264 bytes allocated
==4075==
==4075== 32,816 bytes in 1 blocks are still reachable in loss record 1 of 2
==4075== at 0x4C2BBAF: malloc (vg_replace_malloc.c:299)
==4075== by 0x4EEB813: __alloc_dir (opendir.c:247)
==4075== by 0x4EEB902: opendir_tail (opendir.c:145)
==4075== by 0x108977: dfsdirectory (in /home/alex/Desktop/main)
==4075== by 0x108AE6: main (in /home/alex/Desktop/main)
==4075==
==4075== 32,816 bytes in 1 blocks are still reachable in loss record 2 of 2
==4075== at 0x4C2BBAF: malloc (vg_replace_malloc.c:299)
==4075== by 0x4EEB813: __alloc_dir (opendir.c:247)
==4075== by 0x4EEB902: opendir_tail (opendir.c:145)
==4075== by 0x108977: dfsdirectory (in /home/alex/Desktop/main)
==4075== by 0x108A78: dfsdirectory (in /home/alex/Desktop/main)
==4075== by 0x108AE6: main (in /home/alex/Desktop/main)
==4075==
==4075== LEAK SUMMARY:
==4075== definitely lost: 0 bytes in 0 blocks
==4075== indirectly lost: 0 bytes in 0 blocks
==4075== possibly lost: 0 bytes in 0 blocks
==4075== still reachable: 65,632 bytes in 2 blocks
==4075== suppressed: 0 bytes in 0 blocks
==4075==
==4075== For counts of detected and suppressed errors, rerun with: -v
==4075== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
==4076==
==4076== HEAP SUMMARY:
==4076== in use at exit: 65,632 bytes in 2 blocks
==4076== total heap usage: 4 allocs, 2 frees, 131,264 bytes allocated
==4076==
==4076== 32,816 bytes in 1 blocks are still reachable in loss record 1 of 2
==4076== at 0x4C2BBAF: malloc (vg_replace_malloc.c:299)
==4076== by 0x4EEB813: __alloc_dir (opendir.c:247)
==4076== by 0x4EEB902: opendir_tail (opendir.c:145)
==4076== by 0x108977: dfsdirectory (in /home/alex/Desktop/main)
==4076== by 0x108AE6: main (in /home/alex/Desktop/main)
==4076==
==4076== 32,816 bytes in 1 blocks are still reachable in loss record 2 of 2
==4076== at 0x4C2BBAF: malloc (vg_replace_malloc.c:299)
==4076== by 0x4EEB813: __alloc_dir (opendir.c:247)
==4076== by 0x4EEB902: opendir_tail (opendir.c:145)
==4076== by 0x108977: dfsdirectory (in /home/alex/Desktop/main)
==4076== by 0x108A78: dfsdirectory (in /home/alex/Desktop/main)
==4076== by 0x108AE6: main (in /home/alex/Desktop/main)
==4076==
==4076== LEAK SUMMARY:
==4076== definitely lost: 0 bytes in 0 blocks
==4076== indirectly lost: 0 bytes in 0 blocks
==4076== possibly lost: 0 bytes in 0 blocks
==4076== still reachable: 65,632 bytes in 2 blocks
==4076== suppressed: 0 bytes in 0 blocks
==4076==
==4076== For counts of detected and suppressed errors, rerun with: -v
==4076== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
==4074==
==4074== HEAP SUMMARY:
==4074== in use at exit: 32,816 bytes in 1 blocks
==4074== total heap usage: 3 allocs, 2 frees, 98,448 bytes allocated
==4074==
==4074== 32,816 bytes in 1 blocks are still reachable in loss record 1 of 1
==4074== at 0x4C2BBAF: malloc (vg_replace_malloc.c:299)
==4074== by 0x4EEB813: __alloc_dir (opendir.c:247)
==4074== by 0x4EEB902: opendir_tail (opendir.c:145)
==4074== by 0x108977: dfsdirectory (in /home/alex/Desktop/main)
==4074== by 0x108AE6: main (in /home/alex/Desktop/main)
==4074==
==4074== LEAK SUMMARY:
==4074== definitely lost: 0 bytes in 0 blocks
==4074== indirectly lost: 0 bytes in 0 blocks
==4074== possibly lost: 0 bytes in 0 blocks
==4074== still reachable: 32,816 bytes in 1 blocks
==4074== suppressed: 0 bytes in 0 blocks
==4074==
==4074== For counts of detected and suppressed errors, rerun with: -v
==4074== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
==4073==
==4073== HEAP SUMMARY:
==4073== in use at exit: 0 bytes in 0 blocks
==4073== total heap usage: 2 allocs, 2 frees, 65,632 bytes allocated
==4073==
==4073== All heap blocks were freed -- no leaks are possible
==4073==
==4073== For counts of detected and suppressed errors, rerun with: -v
==4073== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
==4070==
==4070== HEAP SUMMARY:
==4070== in use at exit: 0 bytes in 0 blocks
==4070== total heap usage: 1 allocs, 1 frees, 32,816 bytes allocated
==4070==
==4070== All heap blocks were freed -- no leaks are possible
==4070==
==4070== For counts of detected and suppressed errors, rerun with: -v
==4070== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
此内存泄漏与递归有关。您不关闭堆栈更上层的目录句柄:
==4075== by 0x4EEB902: opendir_tail (opendir.c:145)
==4075== by 0x108977: dfsdirectory (in /home/alex/Desktop/main)
==4075== by 0x108AE6: main (in /home/alex/Desktop/main)
==4075== by 0x4EEB902: opendir_tail (opendir.c:145)
==4075== by 0x108977: dfsdirectory (in /home/alex/Desktop/main)
==4075== by 0x108A78: dfsdirectory (in /home/alex/Desktop/main)
==4075== by 0x108AE6: main (in /home/alex/Desktop/main)
这是 仍然可以访问的 类型的泄漏,这些可能是无害的,因为您提前调用了 exit
(适用于此处),或者因为它们指的是植根于全局变量的数据结构。 C 开发人员之间存在相当大的分歧,是否需要解决这些泄漏,或者将它们留在程序中是否可以接受。
另请注意,glibc 对 closedir
的 EINTR
检查是错误的。它在 EINTR
失败的情况下引入了双重释放漏洞。
我在递归调用之前找到了solution.Close目录,没有任何内存泄漏
当我尝试递归遍历 fork.Fork 中的目录时导致内存泄漏。每个 directory.But valgrind 都说 opendir_tail.I 尝试在父级中写入 clodir 但后来我分配了 1 个但 2 个空闲 error.Where 是问题吗?
这是我的代码。
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <fcntl.h>
#include <string.h>
#include <sys/stat.h>
#include <dirent.h>
#include <errno.h>
#include <ctype.h>
int dfsdirectory (char *path){
DIR* dir;
struct dirent *dirEntry;
struct stat fileStat;
char _PathN[1000];
int totalSize=0;
if (!(dir = opendir(path))){
closedir(dir);
return -1;
}
while ( ((dirEntry=readdir(dir)) != 0) ) {
int dirSize=0;
if (strcmp(dirEntry->d_name, ".") == 0
|| strcmp(dirEntry->d_name, "..") == 0)
continue;
snprintf(_PathN, sizeof(_PathN), "%s/%s", path, dirEntry->d_name);
lstat (_PathN, &fileStat);
if (S_ISDIR(fileStat.st_mode)){
int PID = fork();
if(PID<0){
closedir(dir);
return -1;
}
if(PID == 0){
dfsdirectory(_PathN);
while ((closedir(dir) == -1) && (errno == EINTR));
exit(0);
}
else{
wait(NULL);
}
}
}
closedir(dir);
return totalSize;
}
int main() {
dfsdirectory("A");
}
和 valgrind 输出
==4070== Memcheck, a memory error detector
==4070== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==4070== Using Valgrind-3.12.0.SVN and LibVEX; rerun with -h for copyright
info
==4070== Command: ./main
==4070== Parent PID: 953
==4070==
==4072==
==4072== HEAP SUMMARY:
==4072== in use at exit: 32,816 bytes in 1 blocks
==4072== total heap usage: 3 allocs, 2 frees, 98,448 bytes allocated
==4072==
==4072== 32,816 bytes in 1 blocks are still reachable in loss record 1 of 1
==4072== at 0x4C2BBAF: malloc (vg_replace_malloc.c:299)
==4072== by 0x4EEB813: __alloc_dir (opendir.c:247)
==4072== by 0x4EEB902: opendir_tail (opendir.c:145)
==4072== by 0x108977: dfsdirectory (in /home/alex/Desktop/main)
==4072== by 0x108AE6: main (in /home/alex/Desktop/main)
==4072==
==4072== LEAK SUMMARY:
==4072== definitely lost: 0 bytes in 0 blocks
==4072== indirectly lost: 0 bytes in 0 blocks
==4072== possibly lost: 0 bytes in 0 blocks
==4072== still reachable: 32,816 bytes in 1 blocks
==4072== suppressed: 0 bytes in 0 blocks
==4072==
==4072== For counts of detected and suppressed errors, rerun with: -v
==4072== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
==4071==
==4071== HEAP SUMMARY:
==4071== in use at exit: 0 bytes in 0 blocks
==4071== total heap usage: 2 allocs, 2 frees, 65,632 bytes allocated
==4071==
==4071== All heap blocks were freed -- no leaks are possible
==4071==
==4071== For counts of detected and suppressed errors, rerun with: -v
==4071== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
==4075==
==4075== HEAP SUMMARY:
==4075== in use at exit: 65,632 bytes in 2 blocks
==4075== total heap usage: 4 allocs, 2 frees, 131,264 bytes allocated
==4075==
==4075== 32,816 bytes in 1 blocks are still reachable in loss record 1 of 2
==4075== at 0x4C2BBAF: malloc (vg_replace_malloc.c:299)
==4075== by 0x4EEB813: __alloc_dir (opendir.c:247)
==4075== by 0x4EEB902: opendir_tail (opendir.c:145)
==4075== by 0x108977: dfsdirectory (in /home/alex/Desktop/main)
==4075== by 0x108AE6: main (in /home/alex/Desktop/main)
==4075==
==4075== 32,816 bytes in 1 blocks are still reachable in loss record 2 of 2
==4075== at 0x4C2BBAF: malloc (vg_replace_malloc.c:299)
==4075== by 0x4EEB813: __alloc_dir (opendir.c:247)
==4075== by 0x4EEB902: opendir_tail (opendir.c:145)
==4075== by 0x108977: dfsdirectory (in /home/alex/Desktop/main)
==4075== by 0x108A78: dfsdirectory (in /home/alex/Desktop/main)
==4075== by 0x108AE6: main (in /home/alex/Desktop/main)
==4075==
==4075== LEAK SUMMARY:
==4075== definitely lost: 0 bytes in 0 blocks
==4075== indirectly lost: 0 bytes in 0 blocks
==4075== possibly lost: 0 bytes in 0 blocks
==4075== still reachable: 65,632 bytes in 2 blocks
==4075== suppressed: 0 bytes in 0 blocks
==4075==
==4075== For counts of detected and suppressed errors, rerun with: -v
==4075== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
==4076==
==4076== HEAP SUMMARY:
==4076== in use at exit: 65,632 bytes in 2 blocks
==4076== total heap usage: 4 allocs, 2 frees, 131,264 bytes allocated
==4076==
==4076== 32,816 bytes in 1 blocks are still reachable in loss record 1 of 2
==4076== at 0x4C2BBAF: malloc (vg_replace_malloc.c:299)
==4076== by 0x4EEB813: __alloc_dir (opendir.c:247)
==4076== by 0x4EEB902: opendir_tail (opendir.c:145)
==4076== by 0x108977: dfsdirectory (in /home/alex/Desktop/main)
==4076== by 0x108AE6: main (in /home/alex/Desktop/main)
==4076==
==4076== 32,816 bytes in 1 blocks are still reachable in loss record 2 of 2
==4076== at 0x4C2BBAF: malloc (vg_replace_malloc.c:299)
==4076== by 0x4EEB813: __alloc_dir (opendir.c:247)
==4076== by 0x4EEB902: opendir_tail (opendir.c:145)
==4076== by 0x108977: dfsdirectory (in /home/alex/Desktop/main)
==4076== by 0x108A78: dfsdirectory (in /home/alex/Desktop/main)
==4076== by 0x108AE6: main (in /home/alex/Desktop/main)
==4076==
==4076== LEAK SUMMARY:
==4076== definitely lost: 0 bytes in 0 blocks
==4076== indirectly lost: 0 bytes in 0 blocks
==4076== possibly lost: 0 bytes in 0 blocks
==4076== still reachable: 65,632 bytes in 2 blocks
==4076== suppressed: 0 bytes in 0 blocks
==4076==
==4076== For counts of detected and suppressed errors, rerun with: -v
==4076== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
==4074==
==4074== HEAP SUMMARY:
==4074== in use at exit: 32,816 bytes in 1 blocks
==4074== total heap usage: 3 allocs, 2 frees, 98,448 bytes allocated
==4074==
==4074== 32,816 bytes in 1 blocks are still reachable in loss record 1 of 1
==4074== at 0x4C2BBAF: malloc (vg_replace_malloc.c:299)
==4074== by 0x4EEB813: __alloc_dir (opendir.c:247)
==4074== by 0x4EEB902: opendir_tail (opendir.c:145)
==4074== by 0x108977: dfsdirectory (in /home/alex/Desktop/main)
==4074== by 0x108AE6: main (in /home/alex/Desktop/main)
==4074==
==4074== LEAK SUMMARY:
==4074== definitely lost: 0 bytes in 0 blocks
==4074== indirectly lost: 0 bytes in 0 blocks
==4074== possibly lost: 0 bytes in 0 blocks
==4074== still reachable: 32,816 bytes in 1 blocks
==4074== suppressed: 0 bytes in 0 blocks
==4074==
==4074== For counts of detected and suppressed errors, rerun with: -v
==4074== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
==4073==
==4073== HEAP SUMMARY:
==4073== in use at exit: 0 bytes in 0 blocks
==4073== total heap usage: 2 allocs, 2 frees, 65,632 bytes allocated
==4073==
==4073== All heap blocks were freed -- no leaks are possible
==4073==
==4073== For counts of detected and suppressed errors, rerun with: -v
==4073== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
==4070==
==4070== HEAP SUMMARY:
==4070== in use at exit: 0 bytes in 0 blocks
==4070== total heap usage: 1 allocs, 1 frees, 32,816 bytes allocated
==4070==
==4070== All heap blocks were freed -- no leaks are possible
==4070==
==4070== For counts of detected and suppressed errors, rerun with: -v
==4070== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
此内存泄漏与递归有关。您不关闭堆栈更上层的目录句柄:
==4075== by 0x4EEB902: opendir_tail (opendir.c:145)
==4075== by 0x108977: dfsdirectory (in /home/alex/Desktop/main)
==4075== by 0x108AE6: main (in /home/alex/Desktop/main)
==4075== by 0x4EEB902: opendir_tail (opendir.c:145)
==4075== by 0x108977: dfsdirectory (in /home/alex/Desktop/main)
==4075== by 0x108A78: dfsdirectory (in /home/alex/Desktop/main)
==4075== by 0x108AE6: main (in /home/alex/Desktop/main)
这是 仍然可以访问的 类型的泄漏,这些可能是无害的,因为您提前调用了 exit
(适用于此处),或者因为它们指的是植根于全局变量的数据结构。 C 开发人员之间存在相当大的分歧,是否需要解决这些泄漏,或者将它们留在程序中是否可以接受。
另请注意,glibc 对 closedir
的 EINTR
检查是错误的。它在 EINTR
失败的情况下引入了双重释放漏洞。
我在递归调用之前找到了solution.Close目录,没有任何内存泄漏