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, ¢_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: ----------------------------------------------------------------------------------------------
J'utilise le code ci-dessus pour créer une liste avec tous les chemins de fichier dans un répertoire donné. (Dans mon cas fts.h
ou ftw.h
ne sont pas une option). J'utilise GLib comme bibliothèque de structures de données. J'ai encore des doutes sur la manière dont GLib alloue, désalloue la mémoire?Problème de fuite de mémoire/GLib
Lors de l'appel de g_slist_free (list) je libère également les données contenues dans les éléments? Pourquoi toutes ces fuites de mémoire apparaissent-elles? Valgrind est-il un outil approprié pour résoudre les problèmes de mémoire lors de l'utilisation d'une bibliothèque complexe comme GLib?
EDIT PLUS TARD:
Si je g_slist_foreach(l,(GFunc)g_free,NULL);
, le rapport valgrind est différent, (toutes les fuites de mémoire de « définitivement perdu » se déplacera à « indirectement perdu »). Je ne vois toujours pas le but? Les collections GLib ne peuvent-elles pas être libérées?
Je pense que 'GSList' utilise l'allocateur de tranches par défaut. Si vous définissez la variable d'environnement 'G_SLICE' sur' always-malloc', il retournera à l'aide de malloc/free afin que Valgrind puisse le tracer. – ptomato
vous pouvez utiliser 'g_slist_free_full()' pour libérer le contenu de la liste tout en libérant la liste. – ebassi