使用g_string_free()的free()/ delete / delete [] / realloc()无效

时间:2012-07-18 16:06:25

标签: c segmentation-fault glib libmysql

我有GList,其中包含GSList的集合。该GSlist包含GString的集合。当我释放整个GList时,我会出现分段错误。

现在检查以下代码。

GList *m_rows = NULL;
m_rows = mysql_multiple_rows(mysql, sql1->str);

g_list_foreach(m_rows, mysql_storage_load_settings, &data);
mysql_free_multiple_rows(m_rows); /// <----------------------- works just fine

m_rows = mysql_multiple_rows(mysql, sql2->str);

if(g_list_length(m_rows)>0){
    g_list_foreach(m_rows, mysql_storage_load_accounts, &data);
    mysql_free_multiple_rows(m_rows); /// <----------------------- Segmentation fault!
}else{
    fprintf(stderr, "\e[31m\tUser has no account!\e[0m");
}

所以m_rows仅使用g_string_new()g_slist_prepend()g_list_prepend()进行分配。 g_string_new()创建新的GString并添加到GSList。然后,所有结果GSList都会添加到GList。它发生在mysql_multiple_rows函数中。

他们free使用mysql_free_multiple_rows。这个功能正好相反。

查看清理功能。

static void mysql_free_multiple_rows(GList *table){
    g_list_free_full(table, mysql_free_single_row);
}
static void mysql_free_single_row(gpointer data){
    g_slist_free_full(data, msyql_free_single_row_field); // data here is GSlist
}
static void msyql_free_single_row_field(gpointer data){
    g_string_free(data, TRUE); // data here is GString actually
}

有人能告诉我为什么会收到此错误吗?由于内存分配和解除分配顺序都相同,我不知道为什么会发生这种情况。

  1. Valgrind output
  2. Source file

1 个答案:

答案 0 :(得分:2)

查看代码,您似乎在password中释放mysql_storage_load_accounts()。但是,我没有看到它的任何特殊处理,所以我的猜测是它会被释放两次。