Memory leak / GLib issue.
- by Andrei Ciobanu
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: ----------------------------------------------------------------------------------------------
I am using the above code in order to create a list with all the filepaths in a certain directory. (In my case fts.h or ftw.h are not an option).
I am using GLib as the data structures library. Still I have my doubts in regarding the way GLib is allocating, de-allocating memory ?
When invoking g_slist_free(list) i also free the data contained by the elements ?
Why all those memory leaks appear ?
Is valgrind a suitable tool for profilinf memory issues when using a complex library like GLib ?
LATER EDIT:
If I g_slist_foreach(l,(GFunc)g_free,NULL);, the valgrind report is different, (All the memory leaks from 'definitely lost' will move to 'indirectly lost'). Still I don't see the point ? Aren't GLib collections implement a way to be freed ?