[glib] Bug 158725 - free linked list with data
- From: Ryan Lortie <ryanl src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [glib] Bug 158725 - free linked list with data
- Date: Thu, 28 Oct 2010 15:21:35 +0000 (UTC)
commit 7c184df292f7552423fa7931c843b2f1949c1455
Author: Ryan Lortie <desrt desrt ca>
Date: Fri Oct 16 12:19:06 2009 +0200
Bug 158725 - free linked list with data
Add some helpers for freeing a linked list along with its elements by
providing a GDestroyNotify to call on each of them.
Add a test.
Based on a patch from Cosimo Cecchi.
docs/reference/glib/glib-sections.txt | 2 +
glib/glib.symbols | 2 +
glib/glist.c | 21 ++++++++++-
glib/glist.h | 2 +
glib/gslist.c | 18 +++++++++
glib/gslist.h | 2 +
glib/tests/list.c | 63 +++++++++++++++++++++++++++++++++
7 files changed, 109 insertions(+), 1 deletions(-)
---
diff --git a/docs/reference/glib/glib-sections.txt b/docs/reference/glib/glib-sections.txt
index c547c8c..eefb391 100644
--- a/docs/reference/glib/glib-sections.txt
+++ b/docs/reference/glib/glib-sections.txt
@@ -1992,6 +1992,7 @@ g_list_remove_link
g_list_delete_link
g_list_remove_all
g_list_free
+g_list_free_full
<SUBSECTION>
g_list_alloc
@@ -2048,6 +2049,7 @@ g_slist_remove_link
g_slist_delete_link
g_slist_remove_all
g_slist_free
+g_slist_free_full
g_slist_free_1
g_slist_free1
diff --git a/glib/glib.symbols b/glib/glib.symbols
index d0b3fa9..c421187 100644
--- a/glib/glib.symbols
+++ b/glib/glib.symbols
@@ -649,6 +649,7 @@ g_list_find_custom
g_list_first
g_list_foreach
g_list_free
+g_list_free_full
g_list_free_1
g_list_index
g_list_insert
@@ -1152,6 +1153,7 @@ g_slist_find
g_slist_find_custom
g_slist_foreach
g_slist_free
+g_slist_free_full
g_slist_free_1
g_slist_index
g_slist_insert
diff --git a/glib/glist.c b/glib/glist.c
index c8f7434..6664964 100644
--- a/glib/glist.c
+++ b/glib/glist.c
@@ -172,7 +172,8 @@ g_list_alloc (void)
*
* <note><para>
* If list elements contain dynamically-allocated memory,
- * they should be freed first.
+ * you should either use g_list_free_full() or free them manually
+ * first.
* </para></note>
*/
void
@@ -200,6 +201,24 @@ g_list_free_1 (GList *list)
}
/**
+ * g_list_free_full:
+ * @list: a pointer to a #GList
+ * @free_func: the function to be called to free each element's data
+ *
+ * Convenience method, which frees all the memory used by a #GList, and
+ * calls the specified destroy function on every element's data.
+ *
+ * Since: 2.28
+ */
+void
+g_list_free_full (GList *list,
+ GDestroyNotify free_func)
+{
+ g_list_foreach (list, (GFunc) free_func, NULL);
+ g_list_free (list);
+}
+
+/**
* g_list_append:
* @list: a pointer to a #GList
* @data: the data for the new element
diff --git a/glib/glist.h b/glib/glist.h
index e74ed96..275005c 100644
--- a/glib/glist.h
+++ b/glib/glist.h
@@ -50,6 +50,8 @@ GList* g_list_alloc (void) G_GNUC_WARN_UNUSED_RESULT;
void g_list_free (GList *list);
void g_list_free_1 (GList *list);
#define g_list_free1 g_list_free_1
+void g_list_free_full (GList *list,
+ GDestroyNotify free_func);
GList* g_list_append (GList *list,
gpointer data) G_GNUC_WARN_UNUSED_RESULT;
GList* g_list_prepend (GList *list,
diff --git a/glib/gslist.c b/glib/gslist.c
index dfbd354..f6581a8 100644
--- a/glib/gslist.c
+++ b/glib/gslist.c
@@ -187,6 +187,24 @@ g_slist_free_1 (GSList *list)
}
/**
+ * g_slist_free_full:
+ * @list: a pointer to a #GSList
+ * @free_func: the function to be called to free each element's data
+ *
+ * Convenience method, which frees all the memory used by a #GSList, and
+ * calls the specified destroy function on every element's data.
+ *
+ * Since: 2.28
+ **/
+void
+g_slist_free_full (GSList *list,
+ GDestroyNotify free_func)
+{
+ g_slist_foreach (list, (GFunc) free_func, NULL);
+ g_slist_free (list);
+}
+
+/**
* g_slist_append:
* @list: a #GSList
* @data: the data for the new element
diff --git a/glib/gslist.h b/glib/gslist.h
index 8b01faf..3731ba9 100644
--- a/glib/gslist.h
+++ b/glib/gslist.h
@@ -49,6 +49,8 @@ GSList* g_slist_alloc (void) G_GNUC_WARN_UNUSED_RESULT;
void g_slist_free (GSList *list);
void g_slist_free_1 (GSList *list);
#define g_slist_free1 g_slist_free_1
+void g_slist_free_full (GSList *list,
+ GDestroyNotify free_func);
GSList* g_slist_append (GSList *list,
gpointer data) G_GNUC_WARN_UNUSED_RESULT;
GSList* g_slist_prepend (GSList *list,
diff --git a/glib/tests/list.c b/glib/tests/list.c
index 05bc8e4..084f7ea 100644
--- a/glib/tests/list.c
+++ b/glib/tests/list.c
@@ -294,6 +294,68 @@ test_list_insert (void)
g_list_free (list);
}
+typedef struct
+{
+ gboolean freed;
+ int x;
+} ListItem;
+
+static void
+free_func (gpointer data)
+{
+ ListItem *item = data;
+
+ item->freed = TRUE;
+}
+
+static ListItem *
+new_item (int x)
+{
+ ListItem *item;
+
+ item = g_slice_new (ListItem);
+ item->freed = FALSE;
+ item->x = x;
+
+ return item;
+}
+
+static void
+test_free_full (void)
+{
+ ListItem *one, *two, *three;
+ GSList *slist = NULL;
+ GList *list = NULL;
+
+ slist = g_slist_prepend (slist, one = new_item (1));
+ slist = g_slist_prepend (slist, two = new_item (2));
+ slist = g_slist_prepend (slist, three = new_item (3));
+ g_assert (!one->freed);
+ g_assert (!two->freed);
+ g_assert (!three->freed);
+ g_slist_free_full (slist, free_func);
+ g_assert (one->freed);
+ g_assert (two->freed);
+ g_assert (three->freed);
+ g_slice_free (ListItem, one);
+ g_slice_free (ListItem, two);
+ g_slice_free (ListItem, three);
+
+ list = g_list_prepend (list, one = new_item (1));
+ list = g_list_prepend (list, two = new_item (2));
+ list = g_list_prepend (list, three = new_item (3));
+ g_assert (!one->freed);
+ g_assert (!two->freed);
+ g_assert (!three->freed);
+ g_list_free_full (list, free_func);
+ g_assert (one->freed);
+ g_assert (two->freed);
+ g_assert (three->freed);
+ g_slice_free (ListItem, one);
+ g_slice_free (ListItem, two);
+ g_slice_free (ListItem, three);
+}
+
int
main (int argc, char *argv[])
{
@@ -316,6 +378,7 @@ main (int argc, char *argv[])
g_test_add_func ("/list/remove-all", test_list_remove_all);
g_test_add_func ("/list/first-last", test_list_first_last);
g_test_add_func ("/list/insert", test_list_insert);
+ g_test_add_func ("/list/free-full", test_free_full);
return g_test_run ();
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]