【问题标题】:Invalid free() / delete / delete[] / realloc() with g_string_free()使用 g_string_free() 的 free() / delete / delete[] / realloc() 无效
【发布时间】:2012-07-18 16:06:25
【问题描述】:

我有一个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'd 使用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

【问题讨论】:

  • 我认为我们需要查看更多代码,至少是mysql_storage_load_accounts() 中的一些。它有一些错误情况吗?
  • @MichałGórny 我已经更新了这个问题。查看最后一个链接
  • 除非我遗漏了什么,否则你似乎在 mysql_storage_load_accounts() 中释放了 password。我没有看到任何特殊处理,所以我的第一个猜测是它被释放了两次。
  • 天哪!就是这样。我没看到那条线。你能把它作为答案发布吗@MichałGórny

标签: c segmentation-fault glib libmysql


【解决方案1】:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-08-17
    • 1970-01-01
    • 2020-05-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多