2012-03-07 1 views
3

요청한 파일의 디렉토리를 검색하는 프로그램을 작성 중입니다. 명령 행의 출력은 동일한 이름으로 발견 된 각 파일에 대한 파일에 대한 디렉토리 경로입니다. 어떤 이유로 valgrind를 실행할 때 메모리 누수가 발생합니다. 윈도우 박스에서 리눅스 가상 머신을 사용하고 있습니다.Valgrind malloc leaks

내 valgrind 출력을 업데이트했습니다. 누수가없는 누수가 있지만 여전히 오류가 있습니다.

#include <stdio.h> 
#include <stdlib.h> 
#include <dirent.h> 
#include <sys/types.h> 
#include <string.h> 

struct tree_t { 

    char *name; 
    int nchildren; 
    struct tree_t **children; 
}; 

char *make_path(const char *dirname, const char *filename) { 
    char *fullpath = (char *) malloc((strlen(dirname) + strlen(filename) + 1 + 1) * sizeof(char)); 
    strcat(fullpath, dirname); 
    strcat(fullpath, "/"); 
    strcat(fullpath, filename); 
    return fullpath; 
} 

struct tree_t *get_tree(const char *name) { 
    struct tree_t *tree = (struct tree_t *) malloc(sizeof(struct tree_t)); 
    char *namecp = (char *) malloc((strlen(name) + 1) * sizeof(char)); 
    strcpy(namecp, name); 
    tree->name = namecp; 

    DIR *dir = opendir(name); 
    if (dir == NULL) { 
    tree->nchildren = 0; 
    } else { 
    tree->nchildren = 0; 
    int numsubdirs = 0; 

    struct dirent *entry; 

    while((entry = readdir(dir))) { 
     if (strcmp(entry->d_name,".") != 0 && strcmp(entry->d_name,"..") != 0) { 
     tree->nchildren++; 
     DIR *subdir = opendir(entry->d_name); 
     if (subdir != NULL) { 
      numsubdirs++; 
     } 
     closedir(subdir); 
     } 
    } 

    tree->children = (struct tree_t **) malloc(numsubdirs * sizeof(struct tree_t **)); 
    } 
    closedir(dir); 
    return tree; 
} 

void find_in_tree(const struct tree_t *root, const char *filename) { 
    int i = 0; 

    DIR *dir = opendir(root->name); 

    if (dir != NULL) { 

    struct dirent *entry; 

    while((entry = readdir(dir))) { 
     if (strcmp(entry->d_name,".") != 0 && strcmp(entry->d_name,"..") != 0) { 
     char *fullpath = make_path(root->name, entry->d_name); 
     DIR *subdir = opendir(fullpath); 
     if (subdir != NULL) { 
      root->children[i] = get_tree(fullpath); 
      find_in_tree(root->children[i], filename); 
      free(root->children[i]); 
      i++; 
     } else if (strcmp(entry->d_name, filename) == 0) { 
      printf("%s\n", fullpath); 
     } 
     free(fullpath); 
     } 
    } 
    } 

    free(root->name); 
    free(root->children); 

} 

int main(int argc, char **args) { 
    printf("What root directory do you want to start from?\n"); 
    char rootdir[256]; 
    scanf("%s",rootdir); 

    char searchfile[256]; 
    printf("What file do you want to search for?\n"); 
    int result = scanf("%s",searchfile); 

    if (result == EOF) { 
    printf("\n"); 
    exit(1); 
    } 

    struct tree_t *root = get_tree(rootdir); 
    find_in_tree(root, searchfile); 
    free(root); 

    return 0; 
} 

이 내 memcheck이 실행 된 후에 모습입니다 :

여기 내 코드입니다.

[[email protected] ~]$ valgrind --tool=memcheck --leak-check=yes -v --track-origins=yes ./dirch 
==1464== Memcheck, a memory error detector 
==1464== Copyright (C) 2002-2009, and GNU GPL'd, by Julian Seward et al. 
==1464== Using Valgrind-3.5.0 and LibVEX; rerun with -h for copyright info 
==1464== Command: ./dirch 
==1464== 
--1464-- Valgrind options: 
--1464-- --tool=memcheck 
--1464-- --leak-check=yes 
--1464-- -v 
--1464-- --track-origins=yes 
--1464-- Contents of /proc/version: 
--1464-- Linux version 2.6.18-274.17.1.el5 ([email protected]) (gcc version 4.1.2 20080704 (Red Hat 4.1.2-51)) #1 SMP Wed Jan 4 22:45:44 EST 2012 
--1464-- Arch and hwcaps: AMD64, amd64-sse3-cx16 
--1464-- Page sizes: currently 4096, max supported 4096 
--1464-- Valgrind library directory: /usr/lib64/valgrind 
--1464-- Reading syms from /USERS/STUDENTS/S-Z/V/VOSTERJL/dirch (0x400000) 
--1464-- Reading syms from /usr/lib64/valgrind/memcheck-amd64-linux (0x38000000) 
--1464-- object doesn't have a dynamic symbol table 
--1464-- Reading syms from /lib64/ld-2.5.so (0x3ca2e00000) 
--1464-- Reading suppressions file: /usr/lib64/valgrind/default.supp 
--1464-- REDIR: 0x3ca2e14730 (strlen) redirected to 0x3803e767 (vgPlain_amd64_linux_REDIR_FOR_strlen) 
--1464-- Reading syms from /usr/lib64/valgrind/vgpreload_core-amd64-linux.so (0x4802000) 
--1464-- Reading syms from /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so (0x4a03000) 
==1464== WARNING: new redirection conflicts with existing -- ignoring it 
--1464--  new: 0x3ca2e14730 (strlen    ) R-> 0x04a070b0 strlen 
--1464-- REDIR: 0x3ca2e14550 (index) redirected to 0x4a06f20 (index) 
--1464-- REDIR: 0x3ca2e14700 (strcmp) redirected to 0x4a07180 (strcmp) 
--1464-- Reading syms from /lib64/libc-2.5.so (0x3ca3200000) 
--1464-- REDIR: 0x3ca3279f60 (rindex) redirected to 0x4a06dd0 (rindex) 
--1464-- REDIR: 0x3ca3279b70 (strlen) redirected to 0x4a07070 (strlen) 
Directory? 
dir1 
Search file? 
test.txt 
--1464-- REDIR: 0x3ca3274de0 (malloc) redirected to 0x4a0608a (malloc) 
--1464-- REDIR: 0x3ca3279630 (strcpy) redirected to 0x4a08a70 (strcpy) 
--1464-- REDIR: 0x3ca327ac80 (memmove) redirected to 0x4a07370 (memmove) 
--1464-- REDIR: 0x3ca3272890 (free) redirected to 0x4a05c9a (free) 
--1464-- REDIR: 0x3ca3279280 (strcat) redirected to 0x4a07d40 (strcat) 
==1464== Invalid write of size 8 
==1464== at 0x400AF3: find_in_tree (in /USERS/STUDENTS/S-Z/V/VOSTERJL/dirch) 
==1464== by 0x400C1F: main (in /USERS/STUDENTS/S-Z/V/VOSTERJL/dirch) 
==1464== Address 0x4c2c170 is 0 bytes after a block of size 0 alloc'd 
==1464== at 0x4A0610C: malloc (vg_replace_malloc.c:195) 
==1464== by 0x4009D2: get_tree (in /USERS/STUDENTS/S-Z/V/VOSTERJL/dirch) 
==1464== by 0x400C0B: main (in /USERS/STUDENTS/S-Z/V/VOSTERJL/dirch) 
==1464== 
==1464== Invalid read of size 8 
==1464== at 0x400B0B: find_in_tree (in /USERS/STUDENTS/S-Z/V/VOSTERJL/dirch) 
==1464== by 0x400C1F: main (in /USERS/STUDENTS/S-Z/V/VOSTERJL/dirch) 
==1464== Address 0x4c2c170 is 0 bytes after a block of size 0 alloc'd 
==1464== at 0x4A0610C: malloc (vg_replace_malloc.c:195) 
==1464== by 0x4009D2: get_tree (in /USERS/STUDENTS/S-Z/V/VOSTERJL/dirch) 
==1464== by 0x400C0B: main (in /USERS/STUDENTS/S-Z/V/VOSTERJL/dirch) 
==1464== 
--1464-- REDIR: 0x3ca32795f0 (strcmp) redirected to 0x4a07140 (strcmp) 
dir1/dir2/test.txt 
==1464== Invalid read of size 8 
==1464== at 0x400B2C: find_in_tree (in /USERS/STUDENTS/S-Z/V/VOSTERJL/dirch) 
==1464== by 0x400C1F: main (in /USERS/STUDENTS/S-Z/V/VOSTERJL/dirch) 
==1464== Address 0x4c2c170 is 0 bytes after a block of size 0 alloc'd 
==1464== at 0x4A0610C: malloc (vg_replace_malloc.c:195) 
==1464== by 0x4009D2: get_tree (in /USERS/STUDENTS/S-Z/V/VOSTERJL/dirch) 
==1464== by 0x400C0B: main (in /USERS/STUDENTS/S-Z/V/VOSTERJL/dirch) 
==1464== 
dir1/test.txt 
Search file? 

--1464-- REDIR: 0x3ca327ae20 (memset) redirected to 0x4a07320 (memset) 
==1464== 
==1464== HEAP SUMMARY: 
==1464==  in use at exit: 0 bytes in 0 blocks 
==1464== total heap usage: 22 allocs, 22 frees, 262,763 bytes allocated 
==1464== 
==1464== All heap blocks were freed -- no leaks are possible 
==1464== 
==1464== ERROR SUMMARY: 6 errors from 3 contexts (suppressed: 4 from 4) 
==1464== 
==1464== 2 errors in context 1 of 3: 
==1464== Invalid read of size 8 
==1464== at 0x400B2C: find_in_tree (in /USERS/STUDENTS/S-Z/V/VOSTERJL/dirch) 
==1464== by 0x400C1F: main (in /USERS/STUDENTS/S-Z/V/VOSTERJL/dirch) 
==1464== Address 0x4c2c170 is 0 bytes after a block of size 0 alloc'd 
==1464== at 0x4A0610C: malloc (vg_replace_malloc.c:195) 
==1464== by 0x4009D2: get_tree (in /USERS/STUDENTS/S-Z/V/VOSTERJL/dirch) 
==1464== by 0x400C0B: main (in /USERS/STUDENTS/S-Z/V/VOSTERJL/dirch) 
==1464== 
==1464== 
==1464== 2 errors in context 2 of 3: 
==1464== Invalid read of size 8 
==1464== at 0x400B0B: find_in_tree (in /USERS/STUDENTS/S-Z/V/VOSTERJL/dirch) 
==1464== by 0x400C1F: main (in /USERS/STUDENTS/S-Z/V/VOSTERJL/dirch) 
==1464== Address 0x4c2c170 is 0 bytes after a block of size 0 alloc'd 
==1464== at 0x4A0610C: malloc (vg_replace_malloc.c:195) 
==1464== by 0x4009D2: get_tree (in /USERS/STUDENTS/S-Z/V/VOSTERJL/dirch) 
==1464== by 0x400C0B: main (in /USERS/STUDENTS/S-Z/V/VOSTERJL/dirch) 
==1464== 
==1464== 
==1464== 2 errors in context 3 of 3: 
==1464== Invalid write of size 8 
==1464== at 0x400AF3: find_in_tree (in /USERS/STUDENTS/S-Z/V/VOSTERJL/dirch) 
==1464== by 0x400C1F: main (in /USERS/STUDENTS/S-Z/V/VOSTERJL/dirch) 
==1464== Address 0x4c2c170 is 0 bytes after a block of size 0 alloc'd 
==1464== at 0x4A0610C: malloc (vg_replace_malloc.c:195) 
==1464== by 0x4009D2: get_tree (in /USERS/STUDENTS/S-Z/V/VOSTERJL/dirch) 
==1464== by 0x400C0B: main (in /USERS/STUDENTS/S-Z/V/VOSTERJL/dirch) 
==1464== 
--1464-- 
--1464-- used_suppression:  4 dl-hack3 
==1464== 
==1464== ERROR SUMMARY: 6 errors from 3 contexts (suppressed: 4 from 4) 

감사합니다.

+1

포스트에게 Valgrind의 결과로이 문제를 지적한다. –

+0

어떤 플랫폼입니까? 문제가 될 수 있습니다. Mac에서는 항상 누출이보고됩니다. –

+0

valgrind를'--leak-check-full'과'--track-origins-yes'로 다시 실행하면 유출 된 메모리와 초기화되지 않은 값의 출처를 알 수 있습니다. –

답변

3

각 opendir에 대해서는 closedir으로 닫아야합니다. 이것은 누출의 원인이 될 수 있습니다.

Valgrind의 또한

==468== 65,648 bytes in 2 blocks are definitely lost in loss record 3 of 3 
==468== at 0x4A0610C: malloc (vg_replace_malloc.c:195) 
==468== by 0x3CA3296822: __alloc_dir (in /lib64/libc-2.5.so) 
==468== by 0x400A09: find_in_tree (in /USERS/STUDENTS/S-Z/V/VOSTERJL/dirch) 
==468== by 0x400B0F: find_in_tree (in /USERS/STUDENTS/S-Z/V/VOSTERJL/dirch) 
==468== by 0x400C06: main (in /USERS/STUDENTS/S-Z/V/VOSTERJL/dirch) 
+0

그게 문제의 일부였습니다. 나는 밖으로 closedir를 놓았다. ... 고마워! –

3

트러스트 valgrind 및 귀하의 코드가 아닙니다. 예를 들어

:

char *make_path(const char *dirname, const char *filename) { 
    char *fullpath = (char *) malloc((strlen(dirname) + strlen(filename) + 1 + 1) * sizeof(char)); 
    strcat(fullpath, dirname); 

malloc()에 의해 반환 된 메모리가 초기화되지 않았습니다. 아직 strcat()을 사용할 수 없습니다.

비슷한 ilk의 다른 문제가있을 것입니다. 의심의 여지가 없습니다.