2012-07-18 3 views
0

J'ai un GList qui contient une collection de GSList. Cette liste GS contient une collection de GString. Quand je libère le GList entier, j'obtiens la faute de segmentation.Invalide gratuit()/delete/delete []/realloc() avec g_string_free()

Vérifiez maintenant le code suivant.

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"); 
} 

Alors m_rows ne sont affectés à l'aide g_string_new(), g_slist_prepend() et g_list_prepend(). g_string_new() crée le nouveau GString et ajouté à un GSList. tous les résultants GSList sont ensuite ajoutés à GList. Cela arrive dans la fonction mysql_multiple_rows. Ils sont free en utilisant mysql_free_multiple_rows. Cette fonction fait juste l'inverse.

Voir les fonctions de nettoyage.

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 
} 

Quelqu'un peut-il me dire pourquoi je reçois cette erreur? Comme la séquence d'allocation de mémoire et de désaffectation est la même, je n'ai aucune idée de la raison pour laquelle cela se produit.

  1. Valgrind output
  2. Source file
+2

Je pense que nous devons voir plus de code, au moins une partie de 'mysql_storage_load_accounts()'. A-t-il des conditions d'erreur? –

+0

@ MichałGórny J'ai mis à jour la question. Voir le dernier lien –

+0

Sauf si quelque chose me manque, vous semblez libérer le mot de passe dans mysql_storage_load_accounts() '. Je ne vois aucune manipulation particulière pour cela, donc ma première supposition serait qu'elle soit libérée deux fois. –

Répondre

2

En regardant le code, vous semblez libérer password dans mysql_storage_load_accounts(). Cependant, je ne vois pas de manipulation particulière pour cela, donc je suppose qu'il serait libéré deux fois.