内存泄漏/ GLib问题

时间:2010-06-05 10:03:38

标签: c glib

   1:  /*
   2:   * File:   xyn-playlist.c
   3:   * Author: Andrei Ciobanu
   4:   *
   5:   * Created on June 4, 2010, 12:47 PM
   6:   */
   7:   
   8:  #include <dirent.h>
   9:  #include <glib.h>
  10:  #include <stdio.h>
  11:  #include <stdlib.h>
  12:  #include <sys/stat.h>
  13:  #include <unistd.h>
  14:   
  15:  /**
  16:   * Returns a list all the file(paths) from a directory.
  17:   * Returns 'NULL' if a certain error occurs.
  18:   * @param dir_path.
  19:   * @param A list of gchars* indicating what file patterns to detect.
  20:   */
  21:  GSList *xyn_pl_get_files(const gchar *dir_path, GSList *file_patterns) {
  22:      /* Returning list containing file paths */
  23:      GSList *fpaths = NULL;
  24:      /* Used to scan directories for subdirs. Acts like a
  25:       * stack, to avoid recursion. */
  26:      GSList *dirs = NULL;
  27:      /* Current dir */
  28:      DIR *cdir = NULL;
  29:      /* Current dir entries */
  30:      struct dirent *cent = NULL;
  31:      /* File stats */
  32:      struct stat cent_stat;
  33:      /* dir_path duplicate, on the heap */
  34:      gchar *dir_pdup;
  35:   
  36:      if (dir_path == NULL) {
  37:          return NULL;
  38:      }
  39:   
  40:      dir_pdup = g_strdup((const gchar*) dir_path);
  41:      dirs = g_slist_append(dirs, (gpointer) dir_pdup);
  42:      while (dirs != NULL) {
  43:          cdir = opendir((const gchar*) dirs->data);
  44:          if (cdir == NULL) {
  45:              g_slist_free(dirs);
  46:              g_slist_free(fpaths);
  47:              return NULL;
  48:          }
  49:          chdir((const gchar*) dirs->data);
  50:          while ((cent = readdir(cdir)) != NULL) {
  51:              lstat(cent->d_name, &cent_stat);
  52:              if (S_ISDIR(cent_stat.st_mode)) {
  53:                  if (g_strcmp0(cent->d_name, ".") == 0 ||
  54:                          g_strcmp0(cent->d_name, "..") == 0) {
  55:                      /* Skip "." and ".." dirs */
  56:                      continue;
  57:                  }
  58:                  dirs = g_slist_append(dirs,
  59:                          g_strconcat((gchar*) dirs->data, "/", cent->d_name, NULL));
  60:              } else {
  61:                  fpaths = g_slist_append(fpaths,
  62:                          g_strconcat((gchar*) dirs->data, "/", cent->d_name, NULL));
  63:              }
  64:          }
  65:          g_free(dirs->data);
  66:          dirs = g_slist_delete_link(dirs, dirs);
  67:          closedir(cdir);
  68:      }
  69:      return fpaths;
  70:  }
  71:   
  72:  int main(int argc, char** argv) {
  73:      GSList *l = NULL;
  74:      l = xyn_pl_get_files("/home/andrei/Music", NULL);
  75:      g_slist_foreach(l,(GFunc)printf,NULL);
  76:      printf("%d\n",g_slist_length(l));
  77:      g_slist_free(l);
  78:      return (0);
  79:  }
  80:   
  81:   
  82:  -----------------------------------------------------------------------------------------------==15429== 
  83:  ==15429== HEAP SUMMARY:
  84:  ==15429==     in use at exit: 751,451 bytes in 7,263 blocks
  85:  ==15429==   total heap usage: 8,611 allocs, 1,348 frees, 22,898,217 bytes allocated
  86:  ==15429== 
  87:  ==15429== 120 bytes in 1 blocks are possibly lost in loss record 1 of 11
  88:  ==15429==    at 0x4024106: memalign (vg_replace_malloc.c:581)
  89:  ==15429==    by 0x4024163: posix_memalign (vg_replace_malloc.c:709)
  90:  ==15429==    by 0x40969C1: ??? (in /lib/libglib-2.0.so.0.2400.1)
  91:  ==15429==    by 0x40971F6: g_slice_alloc (in /lib/libglib-2.0.so.0.2400.1)
  92:  ==15429==    by 0x40988A5: g_slist_append (in /lib/libglib-2.0.so.0.2400.1)
  93:  ==15429==    by 0x80488F0: xyn_pl_get_files (xyn-playlist.c:41)
  94:  ==15429==    by 0x8048848: main (main.c:18)
  95:  ==15429== 
  96:  ==15429== 129 bytes in 1 blocks are possibly lost in loss record 2 of 11
  97:  ==15429==    at 0x4024F20: malloc (vg_replace_malloc.c:236)
  98:  ==15429==    by 0x4081243: g_malloc (in /lib/libglib-2.0.so.0.2400.1)
  99:  ==15429==    by 0x409B85B: g_strconcat (in /lib/libglib-2.0.so.0.2400.1)
 100:  ==15429==    by 0x80489FE: xyn_pl_get_files (xyn-playlist.c:62)
 101:  ==15429==    by 0x8048848: main (main.c:18)
 102:  ==15429== 
 103:  ==15429== 360 bytes in 3 blocks are possibly lost in loss record 3 of 11
 104:  ==15429==    at 0x4024106: memalign (vg_replace_malloc.c:581)
 105:  ==15429==    by 0x4024163: posix_memalign (vg_replace_malloc.c:709)
 106:  ==15429==    by 0x40969C1: ??? (in /lib/libglib-2.0.so.0.2400.1)
 107:  ==15429==    by 0x4097222: g_slice_alloc (in /lib/libglib-2.0.so.0.2400.1)
 108:  ==15429==    by 0x40988A5: g_slist_append (in /lib/libglib-2.0.so.0.2400.1)
 109:  ==15429==    by 0x80488F0: xyn_pl_get_files (xyn-playlist.c:41)
 110:  ==15429==    by 0x8048848: main (main.c:18)
 111:  ==15429== 
 112:  ==15429== 508 bytes in 1 blocks are still reachable in loss record 4 of 11
 113:  ==15429==    at 0x402425F: calloc (vg_replace_malloc.c:467)
 114:  ==15429==    by 0x408113B: g_malloc0 (in /lib/libglib-2.0.so.0.2400.1)
 115:  ==15429==    by 0x409624D: ??? (in /lib/libglib-2.0.so.0.2400.1)
 116:  ==15429==    by 0x409710C: g_slice_alloc (in /lib/libglib-2.0.so.0.2400.1)
 117:  ==15429==    by 0x40988A5: g_slist_append (in /lib/libglib-2.0.so.0.2400.1)
 118:  ==15429==    by 0x80488F0: xyn_pl_get_files (xyn-playlist.c:41)
 119:  ==15429==    by 0x8048848: main (main.c:18)
 120:  ==15429== 
 121:  ==15429== 508 bytes in 1 blocks are still reachable in loss record 5 of 11
 122:  ==15429==    at 0x402425F: calloc (vg_replace_malloc.c:467)
 123:  ==15429==    by 0x408113B: g_malloc0 (in /lib/libglib-2.0.so.0.2400.1)
 124:  ==15429==    by 0x409626F: ??? (in /lib/libglib-2.0.so.0.2400.1)
 125:  ==15429==    by 0x409710C: g_slice_alloc (in /lib/libglib-2.0.so.0.2400.1)
 126:  ==15429==    by 0x40988A5: g_slist_append (in /lib/libglib-2.0.so.0.2400.1)
 127:  ==15429==    by 0x80488F0: xyn_pl_get_files (xyn-playlist.c:41)
 128:  ==15429==    by 0x8048848: main (main.c:18)
 129:  ==15429== 
 130:  ==15429== 508 bytes in 1 blocks are still reachable in loss record 6 of 11
 131:  ==15429==    at 0x402425F: calloc (vg_replace_malloc.c:467)
 132:  ==15429==    by 0x408113B: g_malloc0 (in /lib/libglib-2.0.so.0.2400.1)
 133:  ==15429==    by 0x4096291: ??? (in /lib/libglib-2.0.so.0.2400.1)
 134:  ==15429==    by 0x409710C: g_slice_alloc (in /lib/libglib-2.0.so.0.2400.1)
 135:  ==15429==    by 0x40988A5: g_slist_append (in /lib/libglib-2.0.so.0.2400.1)
 136:  ==15429==    by 0x80488F0: xyn_pl_get_files (xyn-playlist.c:41)
 137:  ==15429==    by 0x8048848: main (main.c:18)
 138:  ==15429== 
 139:  ==15429== 1,200 bytes in 10 blocks are possibly lost in loss record 7 of 11
 140:  ==15429==    at 0x4024106: memalign (vg_replace_malloc.c:581)
 141:  ==15429==    by 0x4024163: posix_memalign (vg_replace_malloc.c:709)
 142:  ==15429==    by 0x40969C1: ??? (in /lib/libglib-2.0.so.0.2400.1)
 143:  ==15429==    by 0x40971F6: g_slice_alloc (in /lib/libglib-2.0.so.0.2400.1)
 144:  ==15429==    by 0x40988A5: g_slist_append (in /lib/libglib-2.0.so.0.2400.1)
 145:  ==15429==    by 0x8048A0D: xyn_pl_get_files (xyn-playlist.c:61)
 146:  ==15429==    by 0x8048848: main (main.c:18)
 147:  ==15429== 
 148:  ==15429== 2,040 bytes in 1 blocks are still reachable in loss record 8 of 11
 149:  ==15429==    at 0x402425F: calloc (vg_replace_malloc.c:467)
 150:  ==15429==    by 0x408113B: g_malloc0 (in /lib/libglib-2.0.so.0.2400.1)
 151:  ==15429==    by 0x40970AB: g_slice_alloc (in /lib/libglib-2.0.so.0.2400.1)
 152:  ==15429==    by 0x40988A5: g_slist_append (in /lib/libglib-2.0.so.0.2400.1)
 153:  ==15429==    by 0x80488F0: xyn_pl_get_files (xyn-playlist.c:41)
 154:  ==15429==    by 0x8048848: main (main.c:18)
 155:  ==15429== 
 156:  ==15429== 4,320 bytes in 36 blocks are possibly lost in loss record 9 of 11
 157:  ==15429==    at 0x4024106: memalign (vg_replace_malloc.c:581)
 158:  ==15429==    by 0x4024163: posix_memalign (vg_replace_malloc.c:709)
 159:  ==15429==    by 0x40969C1: ??? (in /lib/libglib-2.0.so.0.2400.1)
 160:  ==15429==    by 0x4097222: g_slice_alloc (in /lib/libglib-2.0.so.0.2400.1)
 161:  ==15429==    by 0x40988A5: g_slist_append (in /lib/libglib-2.0.so.0.2400.1)
 162:  ==15429==    by 0x80489D2: xyn_pl_get_files (xyn-playlist.c:58)
 163:  ==15429==    by 0x8048848: main (main.c:18)
 164:  ==15429== 
 165:  ==15429== 56,640 bytes in 472 blocks are possibly lost in loss record 10 of 11
 166:  ==15429==    at 0x4024106: memalign (vg_replace_malloc.c:581)
 167:  ==15429==    by 0x4024163: posix_memalign (vg_replace_malloc.c:709)
 168:  ==15429==    by 0x40969C1: ??? (in /lib/libglib-2.0.so.0.2400.1)
 169:  ==15429==    by 0x4097222: g_slice_alloc (in /lib/libglib-2.0.so.0.2400.1)
 170:  ==15429==    by 0x40988A5: g_slist_append (in /lib/libglib-2.0.so.0.2400.1)
 171:  ==15429==    by 0x8048A0D: xyn_pl_get_files (xyn-playlist.c:61)
 172:  ==15429==    by 0x8048848: main (main.c:18)
 173:  ==15429== 
 174:  ==15429== 685,118 bytes in 6,736 blocks are definitely lost in loss record 11 of 11
 175:  ==15429==    at 0x4024F20: malloc (vg_replace_malloc.c:236)
 176:  ==15429==    by 0x4081243: g_malloc (in /lib/libglib-2.0.so.0.2400.1)
 177:  ==15429==    by 0x409B85B: g_strconcat (in /lib/libglib-2.0.so.0.2400.1)
 178:  ==15429==    by 0x80489FE: xyn_pl_get_files (xyn-playlist.c:62)
 179:  ==15429==    by 0x8048848: main (main.c:18)
 180:  ==15429== 
 181:  ==15429== LEAK SUMMARY:
 182:  ==15429==    definitely lost: 685,118 bytes in 6,736 blocks
 183:  ==15429==    indirectly lost: 0 bytes in 0 blocks
 184:  ==15429==      possibly lost: 62,769 bytes in 523 blocks
 185:  ==15429==    still reachable: 3,564 bytes in 4 blocks
 186:  ==15429==         suppressed: 0 bytes in 0 blocks
 187:  ==15429== 
 188:  ==15429== For counts of detected and suppressed errors, rerun with: -v
 189:  ==15429== ERROR SUMMARY: 7 errors from 7 contexts (suppressed: 17 from 8)
 190:  ----------------------------------------------------------------------------------------------

我正在使用上面的代码来创建一个包含特定目录中所有文件路径的列表。 (就我而言,fts.hftw.h不是一种选择。

我使用GLib作为数据结构库。关于GLib分配,取消分配内存的方式,我还有疑问吗?

当调用g_slist_free(list)时,我还释放元素包含的数据? 为什么会出现所有这些内存泄漏? 当使用像GLib这样的复杂库时,valgrind是用于profilinf内存问题的合适工具吗?

LATER EDIT:

如果我g_slist_foreach(l,(GFunc)g_free,NULL);,valgrind报告是不同的,('绝对丢失'的所有内存泄漏将转移到'间接丢失')。我还没有看到这一点吗? GLib集合是否实现了一种可以释放的方式?

1 个答案:

答案 0 :(得分:2)

不,g_slist_free不会释放您存储在列表中的数据(例如字符串)。它无法知道您是否以及如何释放此数据。您可以将相同的指针存储在多个列表中。此外,您可以在列表中存储非指针类型,或者未使用malloc分配的类型。该集合不允许您提供析构函数。因此,您需要在释放列表之前循环并释放数据。

此外,g_slist可以使用内存池,因此valgrind可能无法始终提供正确的结果。

其他类型(例如GPtrArray)允许您为元素数据提供析构函数(GDestroyNotify)。