I'm trying to build a GHashTable of instances of a struct containing ints, a time_t and a few char*'s.
我正在尝试构建一个包含整数,一个time_t和一些char *的结构实例的GHashTable。
My question is, how do you insert an instance of a struct into a GHashTable? there are plenty of examples of how to insert a string or an int (using g_str_hash and g_int_hash respectively), but I'm guessing thatI want to use the g_direct_hash, and I can't seem to find any examples of that.
我的问题是,如何在GHashTable中插入结构实例?有很多关于如何插入字符串或int的示例(分别使用g_str_hash和g_int_hash),但我猜我想使用g_direct_hash,我似乎无法找到任何示例。
Ideally, my code would look like this:
理想情况下,我的代码看起来像这样:
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);
Clearly, this is incorrect as it does not compile. Can anyone provide an example that does do what I want? Thanks, Rik
显然,这是不正确的,因为它不编译。任何人都可以提供一个做我想做的事情的例子吗?谢谢,Rik
3 个解决方案
#1
2
You can't insert an automatic variable; you have to allocate memory for the data to store in a dynamic way, i.e. using g_malloc()
or equivalent.
您无法插入自动变量;你必须为数据分配内存以动态方式存储,即使用g_malloc()或等价物。
Then you need to figure out a way to compute a hash value from your data, to help the table be efficient. Using g_direct_hash()
is not very good here; it will use the pointer to your data as the hash value.
然后,您需要找出一种从数据中计算哈希值的方法,以帮助表高效。在这里使用g_direct_hash()并不是很好;它将使用指向您数据的指针作为哈希值。
It seems as if you want to use the member a
of your structure as the key; what type is this field? If it's integer, you can use g_int_hash()
.
好像你想用你的结构的成员a作为关键;这个领域是什么类型的?如果是整数,则可以使用g_int_hash()。
I think this is more along the lines of what your actual code should look like:
我认为这更符合您的实际代码应该是这样的:
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);
Note that this assumes that the b
and d
members are simply character pointers, since no storage is dynamically allocated for the strings.
请注意,这假设b和d成员只是字符指针,因为没有为字符串动态分配存储空间。
#2
1
You have to allocate the structures on the heap so you can store a pointer in the hash table:
您必须在堆上分配结构,以便可以在哈希表中存储指针:
struct SomeType * p = malloc(sizeof(struct SomeType));
p->a = 1;
//etc..
g_hash_table_insert(table,p->a,p);
You'll also need to use g_hash_table_new_full() so you can properly free the pointers when the table is destroyed.
您还需要使用g_hash_table_new_full(),以便在销毁表时正确释放指针。
#3
1
Thanks. The above examples helped. After reading these and going through code samples on the net, I could make it work. Following is a sample working code I wrote:
谢谢。以上例子有所帮助。在阅读完这些并通过网络上的代码示例后,我可以使它工作。以下是我写的示例工作代码:
#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);
}
`
#1
2
You can't insert an automatic variable; you have to allocate memory for the data to store in a dynamic way, i.e. using g_malloc()
or equivalent.
您无法插入自动变量;你必须为数据分配内存以动态方式存储,即使用g_malloc()或等价物。
Then you need to figure out a way to compute a hash value from your data, to help the table be efficient. Using g_direct_hash()
is not very good here; it will use the pointer to your data as the hash value.
然后,您需要找出一种从数据中计算哈希值的方法,以帮助表高效。在这里使用g_direct_hash()并不是很好;它将使用指向您数据的指针作为哈希值。
It seems as if you want to use the member a
of your structure as the key; what type is this field? If it's integer, you can use g_int_hash()
.
好像你想用你的结构的成员a作为关键;这个领域是什么类型的?如果是整数,则可以使用g_int_hash()。
I think this is more along the lines of what your actual code should look like:
我认为这更符合您的实际代码应该是这样的:
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);
Note that this assumes that the b
and d
members are simply character pointers, since no storage is dynamically allocated for the strings.
请注意,这假设b和d成员只是字符指针,因为没有为字符串动态分配存储空间。
#2
1
You have to allocate the structures on the heap so you can store a pointer in the hash table:
您必须在堆上分配结构,以便可以在哈希表中存储指针:
struct SomeType * p = malloc(sizeof(struct SomeType));
p->a = 1;
//etc..
g_hash_table_insert(table,p->a,p);
You'll also need to use g_hash_table_new_full() so you can properly free the pointers when the table is destroyed.
您还需要使用g_hash_table_new_full(),以便在销毁表时正确释放指针。
#3
1
Thanks. The above examples helped. After reading these and going through code samples on the net, I could make it work. Following is a sample working code I wrote:
谢谢。以上例子有所帮助。在阅读完这些并通过网络上的代码示例后,我可以使它工作。以下是我写的示例工作代码:
#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);
}
`