2010-04-19 10 views
2

Je tente de construire un GHashTable d'instances d'une structure contenant ints, un time_t et quelques char *.Insertion de structure non-pod dans un GHashTable

Ma question est, comment insérez-vous une instance d'une structure dans un GHashTable? il y a beaucoup d'exemples d'insertion d'une chaîne ou d'un int (en utilisant respectivement g_str_hash et g_int_hash), mais je suppose que je veux utiliser g_direct_hash, et je n'arrive pas à trouver d'exemples de cela.

Idéalement, mon code ressemblerait à ceci:

GHashtable table; 
table = g_hash_table_new(g_direct_hash, g_direct_equal); 
struct mystruct; 
mystruct.a = 1; 
mystruct.b = "hello"; 
mystruct.c = 5; 
mystruct.d = "test"; 

g_hash_table_insert(table,mystruct.a,mystruct); 

De toute évidence, ce qui est faux car il ne compile pas. Quelqu'un peut-il fournir un exemple qui fait ce que je veux? Merci, Rik

Répondre

1

Vous devez affecter les structures sur le tas de sorte que vous pouvez stocker un pointeur dans la table de hachage:

struct SomeType * p = malloc(sizeof(struct SomeType)); 
p->a = 1; 
//etc.. 
g_hash_table_insert(table,p->a,p); 

Vous devez également utiliser g_hash_table_new_full() pour que vous puissiez bien libère les pointeurs lorsque la table est détruite.

2

Vous ne pouvez pas insérer une variable automatique; vous devez allouer de la mémoire pour les données à stocker de manière dynamique, c'est-à-dire en utilisant g_malloc() ou équivalent.

Ensuite, vous devez trouver un moyen de calculer une valeur de hachage à partir de vos données, pour aider la table à être efficace. En utilisant g_direct_hash() n'est pas très bon ici; il utilisera le pointeur vers vos données comme valeur de hachage.

Il semble que vous souhaitiez utiliser le membre a de votre structure comme clé; quel type est ce champ? Si c'est un entier, vous pouvez utiliser g_int_hash().

Je pense que cela est plus le long des lignes de ce que votre code réel devrait ressembler à:

GHashtable *table; 
struct mystruct *my; 

table = g_hash_table_new_full(g_int_hash, g_int_equal, NULL, g_free); 
my = g_malloc(sizeof *my); 
my->a = 1; 
my->b = "hello"; 
my->c = 5; 
my->d = "test"; 

g_hash_table_insert(table, GINT_TO_POINTER(my->a), my); 

Notez que cela suppose que les b et d membres sont simplement des pointeurs de caractère, car aucun stockage est allouée dynamiquement pour Les cordes.

+0

'table = g_hash_table_new_full (g_int_hash, g_int_equal, NULL, g_free);' – ntd

+0

@ntd: Merci, et fixe! – unwind

+0

une amélioration est d'utiliser g_new (struct mystruct, 1) au lieu de g_malloc. supprime deux sources d'erreur (allocation de taille incorrecte et affectation de la mémoire au mauvais type). –

1

Merci. Les exemples ci-dessus ont aidé. Après avoir lu ceux-ci et passé en revue des exemples de code sur le net, je pourrais le faire fonctionner. Voici un exemple de code de travail que j'ai écrit:

 

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

struct struct_process { 
    int pid; 
    char* file_to_process; 
}; 

typedef struct struct_process Process; 

int main() { 
    GHashTable* hash_table = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, g_free); 

    Process* p1 = (Process*)(malloc(sizeof(Process))); 
    p1->pid = 1234; 
    p1->file_to_process= "/var/tmp/p1"; 

    g_hash_table_insert(hash_table, GINT_TO_POINTER(p1->pid), GINT_TO_POINTER(p1)); 

    # replace 1234 by some other key to see that it returns NULL on nonexistent keys 
    Process* p3 = (Process*)(g_hash_table_lookup(hash_table, GINT_TO_POINTER(1234))); 

    if (p3 == NULL) { 
     printf("could not find\n"); 
    } else { 
     printf("found and i have to process %s\n", p3->file_to_process); 
    } 
    g_hash_table_destroy(hash_table); 
} 
`