2012-03-07 73 views
3

我正在編寫一個程序來搜索所請求文件的目錄。命令行上的輸出將是目錄到文件的路徑,用於找到具有相同名稱的每個文件。由於某些原因,當我使用valgrind運行它時,會導致內存泄漏。 我正在一個windows虛擬機上運行一個linux虛擬機。Valgrind malloc泄漏

我更新了我的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的結果。 – 2012-03-07 03:50:38

+0

什麼平臺?在Mac上,它可能很重要,它至少會報告一些泄漏。 – 2012-03-07 03:51:29

+0

如果你用'--leak-check-full'和'--track-originins-yes'重新運行valgrind,那麼你會看到泄漏的內存和未初始化的值來自哪裏。 – 2012-03-07 04:22:00

回答

3

對於每個操作,您應該關閉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出來....謝謝! – 2012-03-07 04:39:47

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()

毫無疑問,還會有類似的其他問題。