GHashTable 对两个相同输入的响应完全不同
以下是我可以创建的最短的可编译演示。
查看接近尾部的 printf
调用,输出如下。我不知道为什么两个完全相同的语句可以做到这一点。它可能与输入类型有关,但我看不出它可能是什么。
#include <gtk/gtk.h>
#include <libxml/xmlmemory.h>
#include <libxml/parser.h>
int
main (int argc, char *argv[])
{
gtk_init (&argc, &argv);
GtkBuilder * builder = gtk_builder_new ();
GHashTable * table = g_hash_table_new(NULL,NULL);
int i;
char builderdoc[] = "<?xml version=\"1.0\"?>"
"<interface>"
" <requires lib=\"gtk+\" version=\"2.16\"/>"
" <!-- interface-naming-policy project-wide -->"
" <object class=\"GtkCheckButton\" id=\"checkbutton1\">"
" </object>"
"</interface>";
// Load gtkbuilder
gtk_builder_add_from_string (builder, builderdoc, sizeof(builderdoc),NULL);
char * buffer[][2] = {
{"log","checkbutton1"}
};
// Load array of widgets into hash table (Shortened)
for(i = 0; i < sizeof(buffer) / sizeof(char *) / 2; i++){
g_hash_table_insert(table,(gchar *) buffer[i][0],gtk_builder_get_object (builder, (gchar *) buffer[i][1]));
}
// Load xml doc
xmlDocPtr doc;
xmlNodePtr cur;
xmlNodePtr cur2;
char xmldoc[] = "<?xml version=\"1.0\"?>"
"<CsSettings>"
"<options>"
"<check name=\"log\" value=\"1\" />"
"</options>"
"</CsSettings>";
doc = xmlParseMemory(xmldoc, (int) sizeof(xmldoc));
cur = xmlDocGetRootElement(doc);
cur = cur->xmlChildrenNode;
// Find what we're looking for
while (cur != NULL){
if(xmlStrEqual(cur->name, (xmlChar *) "options")){
cur2 = cur->xmlChildrenNode;
while (cur2 != NULL){
if(xmlStrEqual(cur2->name, (xmlChar *) "check")){
// We've found it, now print some output
printf("Plain old lookup: g_hash_table_lookup(table,\"log\"): %p\n",g_hash_table_lookup(table,"log"));
printf("Variable lookup : g_hash_table_lookup(table,\"%s\"): %p\n",(gchar *) xmlGetProp(cur2, (xmlChar *) "name"),g_hash_table_lookup(table,(gchar *) xmlGetProp(cur2, (xmlChar *) "name")));
printf("Xml says we should lookup: '%s'\n",(gchar *) xmlGetProp(cur2, (xmlChar *) "name"));
}
cur2 = cur2->next;
}
}
cur = cur->next;
}
}
以及令人困惑的输出:
Plain old lookup: g_hash_table_lookup(table,"log"): 0x1e369a0
Variable lookup : g_hash_table_lookup(table,"log"): (nil)
Xml says we should lookup: 'log'
What follows is the shortest compilable demonstration of my problem I can create.
Look at the printf
calls near the end, the output follows. I have no idea why two statements that are exactly the same can possibly do this. It probably has something to do with input type but I can't see what it could be.
#include <gtk/gtk.h>
#include <libxml/xmlmemory.h>
#include <libxml/parser.h>
int
main (int argc, char *argv[])
{
gtk_init (&argc, &argv);
GtkBuilder * builder = gtk_builder_new ();
GHashTable * table = g_hash_table_new(NULL,NULL);
int i;
char builderdoc[] = "<?xml version=\"1.0\"?>"
"<interface>"
" <requires lib=\"gtk+\" version=\"2.16\"/>"
" <!-- interface-naming-policy project-wide -->"
" <object class=\"GtkCheckButton\" id=\"checkbutton1\">"
" </object>"
"</interface>";
// Load gtkbuilder
gtk_builder_add_from_string (builder, builderdoc, sizeof(builderdoc),NULL);
char * buffer[][2] = {
{"log","checkbutton1"}
};
// Load array of widgets into hash table (Shortened)
for(i = 0; i < sizeof(buffer) / sizeof(char *) / 2; i++){
g_hash_table_insert(table,(gchar *) buffer[i][0],gtk_builder_get_object (builder, (gchar *) buffer[i][1]));
}
// Load xml doc
xmlDocPtr doc;
xmlNodePtr cur;
xmlNodePtr cur2;
char xmldoc[] = "<?xml version=\"1.0\"?>"
"<CsSettings>"
"<options>"
"<check name=\"log\" value=\"1\" />"
"</options>"
"</CsSettings>";
doc = xmlParseMemory(xmldoc, (int) sizeof(xmldoc));
cur = xmlDocGetRootElement(doc);
cur = cur->xmlChildrenNode;
// Find what we're looking for
while (cur != NULL){
if(xmlStrEqual(cur->name, (xmlChar *) "options")){
cur2 = cur->xmlChildrenNode;
while (cur2 != NULL){
if(xmlStrEqual(cur2->name, (xmlChar *) "check")){
// We've found it, now print some output
printf("Plain old lookup: g_hash_table_lookup(table,\"log\"): %p\n",g_hash_table_lookup(table,"log"));
printf("Variable lookup : g_hash_table_lookup(table,\"%s\"): %p\n",(gchar *) xmlGetProp(cur2, (xmlChar *) "name"),g_hash_table_lookup(table,(gchar *) xmlGetProp(cur2, (xmlChar *) "name")));
printf("Xml says we should lookup: '%s'\n",(gchar *) xmlGetProp(cur2, (xmlChar *) "name"));
}
cur2 = cur2->next;
}
}
cur = cur->next;
}
}
And the gloriously confusing output:
Plain old lookup: g_hash_table_lookup(table,"log"): 0x1e369a0
Variable lookup : g_hash_table_lookup(table,"log"): (nil)
Xml says we should lookup: 'log'
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您可能会从哈希表中得到意外的行为,因为您没有在构造函数上设置任何哈希或相等函数,在这种情况下,使用
g_direct_hash()
和g_direct_equal( 在指针上直接进行哈希处理)
函数适用。如果表的键是
gchar *
我会使用g_str_hash
和g_str_equal
。像这样初始化你的表:GHashTable * table = g_hash_table_new(g_str_hash,g_str_equal);
如果哈希表的键是要存储的内容,那么直接对指针进行哈希不是一个好主意指针所指的是。请告诉我们这是否可以解决问题。
You might be getting unexpected behaviour from the hash table because you aren't setting any hash or equal function on the constructor, in such case direct hashing on the pointer with
g_direct_hash()
andg_direct_equal()
functions applies.If the key of the table is
gchar *
I'd useg_str_hash
andg_str_equal
. Something like this to init your table:GHashTable * table = g_hash_table_new(g_str_hash,g_str_equal);
Direct hashing on the pointer isn't a good idea, if the key of the hash table is the content to wich the pointer is referring to. Pls, let us know if this fixes the issue.