我们是否需要释放GLIB中列表中的每个元素

时间:2015-08-04 10:24:40

标签: c list memory-management free glib

我一直在看这份文件here

,代码是:

#include <glib.h>
void print_iterator(gpointer item, gpointer prefix) {
 printf("%s %s\n", prefix, item);
}
void print_iterator_short(gpointer item) {
 printf("%s\n", item);
}
int main(int argc, char** argv) {
 GSList* list = g_slist_append(NULL, g_strdup("first"));
 list = g_slist_append(list, g_strdup("second"));
 list = g_slist_append(list, g_strdup("third"));
 printf("Iterating with a function:\n");
 g_slist_foreach(list, print_iterator, "-->");
 printf("Iterating with a shorter function:\n");
 g_slist_foreach(list, (GFunc)print_iterator_short, NULL);
 printf("Now freeing each item\n");
 g_slist_foreach(list, (GFunc)g_free, NULL);
 g_slist_free(list);
 return 0;
}

这里使用循环释放列表中的每个元素。在前面的示例中,只需将整个列表释放为g_slist_free(list);,在此示例中显示列表中的每个元素都使用foreach循环释放。

我们是否需要释放每个元素或释放整个列表就足够了?

2 个答案:

答案 0 :(得分:4)

来自:https://developer.gnome.org/glib/stable/glib-Singly-Linked-Lists.html#g-slist-free

void
g_slist_free (GSList *list);
  

释放GSList使用的所有内存。释放的元素是   返回切片分配器。如果列表元素包含   动态分配的内存,你应该使用   g_slist_free_full()或先手动释放

所以是的,您必须先释放每个元素或使用 g_slist_free_full()

答案 1 :(得分:1)

取决于列表包含的内容。

g_slist_free()只释放列表节点自身占用的内存,因为它不知道列表中存储的内容(GSList不是类型安全的)。它不会触及列表节点中的data指针。

在您的示例中,列表包含使用strdup分配的C字符串,因此您必须在释放列表节点之前释放它们。但是,如果您的列表包含指向常量数据的指针,或者data字段存储类型为void*的整数,那么您应该释放元素。

通常,当且仅当列表节点中的data指针指向动态分配的内存时,才必须在释放列表之前释放元素:从malloc获得的内容,{{1} },g_malloc