简体   繁体   English

Valgrind malloc泄漏

[英]Valgrind malloc leaks

I'm writing a program to search though directories for a requested file. 我正在编写一个程序来搜索所请求文件的目录。 The output on command line will be the path of the directory to the file, for each file found with the same name. 对于找到的具有相同名称的每个文件,命令行上的输出将是文件目录的路径。 For some reason it is giving memory leaks when I run it with valgrind. 出于某种原因,当我使用valgrind运行它时会出现内存泄漏。 I am running on a linux virtual machine on a windows box. 我在Windows机器上的Linux虚拟机上运行。

I updated my valgrind output. 我更新了我的valgrind输出。 I have no leaks free leaks but still errors. 我没有泄漏泄漏,但仍然有错误。

Here's my code: 这是我的代码:

#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;
}

This is what my memcheck looks like after being run. 这是我的memcheck在运行后的样子。

[vosterjl@clark ~]$ 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 (mockbuild@hs20-bc2-5.build.redhat.com) (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)

Anything will help, thanks! 什么都有帮助,谢谢!

Trust valgrind and not your code. 信任valgrind而不是你的代码。

For instance: 例如:

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

The memory returned by malloc() is not initialized. malloc()返回的malloc()未初始化。 You can't use strcat() yet. 你还不能使用strcat()

There will be other problems of a similar ilk, no doubt. 毫无疑问,会有其他类似的问题。

For each opendir you do, you should close with a closedir Please check. 对于你做的每个opendir,你应该关闭一个closedir请检查。 This can be source of your leaks. 这可能是您的泄漏源。

Valgrind is also pointing this out to you 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) 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM