Many thanks, the problem was destroying c & d. All I need now is to have a dynamic list (insert, update, delete) keeping the client struct. I thought hash tables would be nice cause they provide fast lookups. This implies keeping in memory, besides the GHashTable, also an array of client. Is there another way of doing what I would like using glib/gtk?
On Tue, 2006-03-14 at 11:12 +0100, David Necas (Yeti) wrote: > On Tue, Mar 14, 2006 at 11:48:56AM +0200, Adrian Vasile wrote: > > I'm having trouble understanding the GHashTable and it's member > > functions. > > GHashTable just stores some untyped pointers. > > Since it has no idea what type the stored data are, it > cannot make a copies of them and does not make copies of > them. So... > > > I've made the following simple code for testing purposes: > > > > #include <stdio.h> > > #include <glib.h> > > > > typedef struct _client > > { > > guint id; > > guint win; > > gchar *name; > > gchar *number; > > gboolean mute; > > } client ; > > > > static void print_hash_kv (gpointer key, gpointer value, gpointer > > user_data) > > { > > gchar *i = (gchar *) key; > > client *d = (client *) value; > > > > printf ("<-- %s -> %d , %s, %s in %d.\n", i, d->id, d->name, d->number, > > d->win); > > } > > > > int main (int argc, char **argv) > > { > > client *c, *d; > > GHashTable *hash = g_hash_table_new (g_str_hash, g_str_equal); > > > > if ((c = g_new (client, 1)) == NULL) > > This cannot happen. g_new() aborts program when it fails to > allocate the memory. > > > { > > printf ("unable to alloc c"); > > return 1; > > } > > > > c->id = 2; > > c->win = 3; > > c->name = g_strdup ("client1"); > > c->number = g_strdup ("0123456789"); > > c->mute = TRUE; > > > > printf ("--> %d , %s, %s in %d.\n", c->id, c->name, c->number, c->win); > > > > g_hash_table_insert (hash, g_strdup ("2"), c); > > I wonder who is going to free the key. Perhaps you intended > to use g_hash_table_new_full() and supply a key destroy > function? Or just get rid of the g_strdup() if keys are > constant strings. > > > g_free (c); > > Now the table contains a pointer to freed memory at key "2". > The c you freed here is the same chunk of memory as is > stored in the table. Remember, no copies, it just stores > some pointer. > > > hash = g_hash_table_ref (hash); > > I wonder what is this intended to mean. You already own > a reference to the hash table -- the initial one. And > I cannot see any g_hash_table_unref() here, so you will have > two *two* reference to the hash table to the end of program. > Why? > > > if ((d = g_new (client, 1)) == NULL) > > { > > printf ("unable to alloc d"); > > return 1; > > } > > > > d->id = 1; > > d->win = 2; > > d->name = g_strdup ("client2"); > > d->number = g_strdup ("9876543210"); > > d->mute = FALSE; > > > > printf ("--> %d , %s, %s in %d.\n", d->id, d->name, d->number, d->win); > > > > g_hash_table_insert (hash, g_strdup ("1"), d); > > Again, the key is likely to be leaked. > > > g_free (d); > > Again, this makes the item at key "1" invalid (pointer to > freed memory). > > > printf ("done inserting..... \n"); > > > > g_hash_table_foreach (hash, print_hash_kv, NULL); > > > > return 0; > > } > > > > The thing is that the output is quite annoying: > > --> 2 , client1, 0123456789 in 3. > > --> 1 , client2, 9876543210 in 2. > > done inserting..... > > <-- 1 -> 0 , client2, 9876543210 in 2. > > <-- 2 -> 0 , client2, 9876543210 in 2. > > The memory block orignially allocated for c (and then freed) > was reused for d. After d was freed too it was not reused > for anything else yet -- you'd get totally bogus values then. > > > My question is how do I manage to get the hash table to actually give me > > back all the my inserts > > Don't destroy them. > > Yeti > > > -- > That's enough. _______________________________________________ gtk-app-devel-list mailing list gtk-app-devel-list@gnome.org http://mail.gnome.org/mailman/listinfo/gtk-app-devel-list