Вставка не-pod структуры в GHashTable - PullRequest
2 голосов
/ 19 апреля 2010

Я пытаюсь создать GHashTable из экземпляров структуры, содержащей int, time_t и несколько символов *.

Мой вопрос: как вставить экземпляр структуры в GHashTable? Есть много примеров того, как вставить строку или int (используя g_str_hash и g_int_hash соответственно), но я предполагаю, что я хочу использовать g_direct_hash, и я не могу найти какие-либо примеры этого.

В идеале мой код должен выглядеть так:

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);

Понятно, что это неправильно, так как не компилируется. Кто-нибудь может привести пример, который делает то, что я хочу? Спасибо, Рик

Ответы [ 3 ]

2 голосов
/ 19 апреля 2010

Вы не можете вставить автоматическую переменную; Вы должны выделить память для данных для динамического хранения, то есть, используя g_malloc() или эквивалентный.

Затем вам нужно найти способ вычислить значение хеш-функции из ваших данных, чтобы помочь таблице быть эффективной. Использование g_direct_hash() здесь не очень хорошо; в качестве хеш-значения он будет использовать указатель на ваши данные.

Кажется, что вы хотите использовать элемент a вашей структуры в качестве ключа; какой тип это поле? Если это целое число, вы можете использовать <a href="http://g_int_hash">g_int_hash()</a>.

Я думаю, это больше похоже на то, как должен выглядеть ваш реальный код:

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);

Обратите внимание, что это предполагает, что члены b и d являются просто символьными указателями, поскольку для строк динамически не выделяется память.

1 голос
/ 31 октября 2010

Спасибо. Приведенные выше примеры помогли. Прочитав их и пройдя примеры кода в сети, я смог заставить его работать. Ниже приведен пример рабочего кода, который я написал:

<code>
#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);
}
</code>`
1 голос
/ 19 апреля 2010

Вы должны выделить структуры в куче, чтобы вы могли сохранить указатель в хеш-таблице:

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

Вам также нужно будет использовать g_hash_table_new_full (), чтобы вы могли правильно освободить указатели при уничтожении таблицы.

...