Ломаю голову над тем, почему в хеш-таблице получаю либо SIGSEGV, либо "мусор" вместо данных по ключу.
Собственно, балуюсь с loudmouth, xmpp библиотекой на Си. Создаю хеш-таблицу, ключ - имя jabber конференции, значение - GList, со структурами whois_t.
Инициирую таблицу:
Код: Выделить всё
GHashTable *hash_whois;
hash_whois = g_hash_table_new_full(g_direct_hash, g_direct_equal, g_free, hash_whois_destroy);При входе в конференцию в таблицу добавляется пустой GList:
Код: Выделить всё
GList *list_whois = g_new(GList, 1);
g_hash_table_insert(hash_whois, g_strdup(argv[1]), list_whois); //argv[1] - имя конференцииЗатем из <presence>...</presence> сообщений берутся данные для whois струкуты:
Код: Выделить всё
struct _whois {
gchar *room;
gchar *nick;
gchar *jid;
gchar *affil;
gchar *role;
};
typedef struct _whois whois_t;Код: Выделить всё
whois_t *whois = g_new(whois_t, 1);
whois->room = g_strdup(strip_jid(from));
whois->nick = strip_res(from);
whois->jid = jid ? g_strdup(jid) : NULL;
whois->affil = g_strdup(affil);
whois->role = g_strdup(role);Из хеш-таблицы достаётся GList соответствующей конференции и в этот лист добавляется whois_t структура:
Код: Выделить всё
GList *list_whois = g_hash_table_lookup(hash_whois, strip_jid(from));
list_whois = g_list_append(list_whois, whois);
g_hash_table_replace(hash_whois, g_strdup(strip_jid(from)), list_whois);По моему всё верно, однако на деле что-то не то:
Код: Выделить всё
void see_whois(gpointer key, gpointer value, gpointer data) {
printf("see_whois:\n");
if(key && value) {
printf("\tkey == %s\n", (char *)key);
GList *list = value;
for(; list; list=list->next) {
whois_t *wh = list->data;
if(wh->room) printf("\t%s\n", wh->room);
if(wh->nick) printf("\t%s\n", wh->nick);
if(wh->jid) printf("\t%s\n", wh->jid);
if(wh->affil) printf("\t%s\n", wh->affil);
if(wh->role) printf("\t%s\n", wh->role);
}
}
}
...
g_hash_table_foreach(hash_whois, see_whois, NULL);gdb:
Breakpoint 1, see_whois (key=0x8058870, value=0x8059d28, data=0x0) at commands.c:22
22 printf("see_whois:\n");
(gdb)
see_whois:
23 if(key && value) {
(gdb)
24 printf("\tkey == %s\n", (char *)key);
(gdb)
key == ololo@muc.varloghost.co.cc
25 GList *list = value;
(gdb)
26 for(; list; list=list->next) {
(gdb)
27 whois_t *wh = list->data;
(gdb)
28 if(wh->room) printf("\t%s\n", wh->room);
(gdb)
29 if(wh->nick) printf("\t%s\n", wh->nick);
(gdb)
Program received signal SIGSEGV, Segmentation fault.
0xb7dc17bb in vfprintf () from /lib/libc.so.6
(gdb)
Очевидно, что забыл где-то на что-то выделить память. Прошу помочь найти.