Invalid free() / delete / delete[] / realloc() with g_string_free()
-
21-06-2021 - |
Question
I have a GList
which contains a collection of GSList
. This GSlist contains a collection of GString
. When I free the whole GList
, I get segmentation fault.
Now check the following code.
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");
}
So m_rows
are only allocated using g_string_new()
, g_slist_prepend()
and g_list_prepend()
. g_string_new()
creates new GString
and added to a GSList
. all the resultant GSList
then get added to GList
. It happens in mysql_multiple_rows
function.
They are free
'd using mysql_free_multiple_rows
. This function just does the reverse.
See the clean up functions.
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
}
Could anyone tell me why I am getting this error? As both the memory allocation and de-allocation sequence are same I have no clue why its happening.
Solution
Looking at the code, you seem to be freeing password
in mysql_storage_load_accounts()
. However, I don't see any special handling for it, so my guess would be that it gets freed twice.