2010-06-05 204 views
1
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作爲數據結構庫。儘管如此,我仍然懷疑GLib是在分配內存還是分配內存?

當調用g_slist_free(list)時,我還可以釋放元素中包含的數據嗎? 爲什麼所有這些內存泄漏出現? 當使用像GLib這樣的複雜庫時,valgrind是否是profilinf內存問題的合適工具?

以後編輯:

如果我g_slist_foreach(l,(GFunc)g_free,NULL);,該報告Valgrind的是不同的,(從「絕對丟失」的所有內存泄漏將移動到「間接丟失」)。我仍然沒有看到這一點? GLib集合是不是實現了一種被釋放的方式?

回答

2

不,g_slist_free不會釋放存儲在列表中的數據(例如字符串)。它無法知道您是否以及如何釋放這些數據。您可能會將相同的指針存儲在多個列表中。此外,您可以將非指針類型存儲在列表中,或者不用malloc分配的類型。該集合不允許您提供析構函數。所以你需要在釋放列表之前循環並釋放數據。

此外,g_slist可以使用內存池,所以valgrind可能不總是給出正確的結果。

其他類型,如GPtrArray,讓您爲元素數據提供析構函數(GDestroyNotify)。

+3

我認爲'GSList'默認使用slice分配器。如果將環境變量'G_SLICE'設置爲'always-malloc',那麼它將返回使用malloc/free,Valgrind可以跟蹤它。 – ptomato 2010-06-08 09:58:22

+2

你可以使用'g_slist_free_full()'來釋放列表的內容,同時釋放列表。 – ebassi 2014-05-19 16:11:04