Here is the problem:
I have a g_hash_table, using the direct hashing function. This hash table holds string(key)->int(value) pairs. In my program, there are two functions: one takes a hash table, and writes the values to GConf; the other reads the values from GConf and returns a new hash table.
To test my functions, I create some data and store it in the hash table, using the following code:
GHashTable *tmp_outputs = g_hash_table_new (NULL, NULL);
gchar *tmp_output_id = g_strdup ("StringOfLettersWithNoSpaces");
gint *tmp_crtc_con = (gint *)g_malloc0 (sizeof(gint));
*tmp_crtc_con = 2;
g_hash_table_insert (tmp_outputs, (gpointer)tmp_output_id, (gpointer)tmp_crtc_con);
Later on in the program, I retrieve this information to dump it to GConf. When I retrieve it, it is perfectly intact. No problems what so ever. I use the following code:
/* This is a nested function */
void process_outputs (gpointer key, gpointer val, gpointer data)
{
cur_key = g_strconcat (profile_path, "/outputs/", (gchar *)key, NULL);
gconf_client_set_int (self->gconf_client, cur_key, *(int *)val, NULL);
g_free (cur_key);
}
g_hash_table_foreach (profile->outputs, process_outputs, NULL);
Again, no problems. Data is fine. I then dump the data to GConf. Using gconf-editor, I manually verify the data is intact; it is. So, I extract it from GConf, and insert it into a hash-table again, using the following code:
GSList *li;
GHashTable *outputs;
outputs = g_hash_table_new (NULL, NULL);
li = gconf_client_all_entries (self->gconf_client, path, NULL);
while (li)
{
gint *val = (gint *) g_malloc0 (sizeof(gint));
GConfEntry *cur_entry = (GConfEntry *)li->data;
gchar* key = g_path_get_basename (cur_entry->key);
*val = gconf_value_get_int (cur_entry->value);
g_hash_table_insert (outputs, (gpointer)key, (gpointer)val);
g_free (key);
gconf_entry_free (cur_entry);
li = li->next;
}
Again, I verify that val is still "StringOfLettersWithNoSpaces" - it is.
However, when I finally extract it from that second hash table to verify it is still in tact, the first four bytes of the string are garbage. No matter what the string is, not matter what I try, the first four bytes point to random memory. I get something like "X�ngOfLettersWithNoSpaces". Of course, the first four characters ("Stri" in this case) always get scrambled.
As far as I can tell, I am treating both hash tables identically. In both cases, I have a gchar* to a newly allocated string, and a gint* to a newly allocated gint. I cast the pointers to gpointer and pass them into the hash table. The first time it works, the second time it doesn't.
What's worse, I try to replicate the problem with the following code:
#include <stdio.h>
#include <glib.h>
int main()
{
GHashTable *table1, *table2;
gchar *key1, *key2;
gint val1, val2;
gchar *temp = "/a/bunch/of/path/with/a/StringOfLettersWithNoSpaces";
val1 = val2 = 10;
key1 = g_strdup ("StringOfLettersWithNoSpaces");
key2 = g_path_get_basename (temp);
table1 = g_hash_table_new (NULL, NULL);
table2 = g_hash_table_new (NULL, NULL);
g_hash_table_insert (table1, (gpointer)key1, (gpointer)&val1);
g_hash_table_insert (table2, (gpointer)key2, (gpointer)&val2);
void temp_foreach (gpointer key, gpointer val, gpointer data) {
printf ("key: %s, val: %d\n", (gchar*)key, *(gint*)val);
}
g_hash_table_foreach (table1, temp_foreach, NULL);
g_hash_table_foreach (table2, temp_foreach, NULL);
return 0;
}
Here is the output:
key: StringOfLettersWithNoSpaces, val: 10
key: StringOfLettersWithNoSpaces, val: 10
What the heck is going in here???