gpt4 book ai didi

c - 使用 GSList 作为 GHashTable 值的不同方法

转载 作者:行者123 更新时间:2023-11-30 14:36:41 29 4
gpt4 key购买 nike

给出代码片段:

#include <glib.h>
#include <stdio.h>

void print_city(gpointer value, gpointer data)
{
printf("%s, ", value);
}
void print(gpointer key, gpointer value, gpointer data)
{
printf("Here are some cities in %s: ", key);
g_slist_foreach((GSList *)value, (GFunc)print_city, NULL);
printf("\n");
}

void destroy(gpointer key, gpointer value, gpointer data)
{
printf("Freeing a GSList, first item is %s\n", ((GSList*)value)->data);
g_slist_free(value);
}

int main(int argc, char *argv[])
{
GHashTable *hash = g_hash_table_new(g_str_hash, g_str_equal);

g_hash_table_insert(hash,
"Virginia",
g_slist_append(g_hash_table_lookup(hash, "Virginia"), "Richmond")
);

g_hash_table_insert(hash,
"Virginia",
g_slist_append(g_hash_table_lookup(hash, "Virginia"), "Keysville")
);

g_hash_table_insert(hash,
"Texas",
g_slist_append(g_hash_table_lookup(hash, "Texas"), "Houston")
);

g_hash_table_insert(hash,
"Texas",
g_slist_append(g_hash_table_lookup(hash, "Texas"), "Austin")
);

g_hash_table_foreach(hash, print, NULL);
g_hash_table_foreach(hash, destroy, NULL);
g_hash_table_destroy(hash);
return 0;
}

我们可以注意到 main 中的行调用 g_hash_table_insert 的函数,看起来有点复杂,重复本身,因此我正在寻找代码替代方案来简化值参数。考虑到这一点,我第一次尝试更改代码如下(已添加注释)

GSList *list = NULL;

// Adding the first element to `list`
// list contains the pointer to the GSList head
list = g_slist_append(list, "Austin");

// Inserting the list (an address to a GSLIST) into
// the value of "Texas" key.
g_hash_table_insert(hash, "Texas", list);

// Retrieves the content of "Texas" key.
// (That is right now the pointer to the GSList head)
// and stores into value pointer
list = g_hash_table_lookup(hash, "Texas");

// Add the string "Houston" to the GSList and stores
// the new head at `value` to keep track of head.
list = g_slist_append(list, "Houston");

// Updates the 'key' Texas with list.
g_hash_table_insert(hash, "Texas", list);

看起来并没有好多少。我还在代码中添加了一些注释来描述我的理解。

问题1:我的理解(在评论中表达)是否正确?

问题2:保持代码一致性,有没有办法改进上面的代码?

我注意到我可以删除对 g_hash_table_insert 的所有调用在第一个之后,可能会牺牲一些一致性。本例中的代码如下所示

GSList *list = NULL;

list = g_slist_append(list, "Austin");
g_hash_table_insert(hash, "Texas", list);
list = g_hash_table_lookup(hash, "Texas");
list = g_slist_append(list, "Houston");

问题 3:此更改如何影响一致性?

问题 4:此更改可能会出现哪些行为?

无论如何,考虑到前面的代码片段,我试图让事情变得更加“有组织”,因此我到达了以下代码片段来更新 GHashTable 中的列表:

GSList *list = NULL;
g_hash_table_insert(hash, "Texas", list);
list = g_hash_table_lookup(hash, "Texas");

list = g_slist_append(list, "Austin");
list = g_slist_append(list, "Houston");

上面的代码看起来更有条理,但在工作中完全失败(甚至在 free 调用上触发段错误)。我无法理解为什么最后一个片段失败了。

问题 5:为什么会发生段错误?

问题 6:是否有更简单的方法来处理 GSListsGHashTables不使用初始构造?

最佳答案

GSList *list = NULL;
g_hash_table_insert(hash, "Texas", list);
list = g_hash_table_lookup(hash, "Texas");
list = g_slist_append(list, "Austin");
list = g_slist_append(list, "Houston");

这里你的哈希表只包含 NULL。即使前面的示例看起来很可疑,实际上也不能保证有效:只要您修改列表,头指针都可能会发生变化。

执行您想要的操作的最简单方法是首先构建列表,然后将其添加到哈希表中:

GSList *list = g_slist_append(NULL, "Austin");
list = g_slist_append(list, "Houston");
g_hash_table_insert(hash, "Texas", list);

但是任何时候你想要修改列表,你都必须将其重新插入到哈希表中...我建议重新考虑你的数据结构选择:链接列表并不是真正适合任何东西(并且 GLib 实现尤其如此)你发现很烦人)。 GSequence、GArray(甚至带有 g_hash_table_add() 的 GHashTable)可能是 GLib 中合适的替代方案。

关于c - 使用 GSList 作为 GHashTable 值的不同方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57920143/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com