GHashTable 对两个相同输入的响应完全不同

发布于 2024-11-05 11:13:35 字数 2720 浏览 6 评论 0原文

以下是我可以创建的最短的可编译演示。

查看接近尾部的 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

谁与争疯 2024-11-12 11:13:35

您可能会从哈希表中得到意外的行为,因为您没有在构造函数上设置任何哈希或相等函数,在这种情况下,使用 g_direct_hash()g_direct_equal( 在指针上直接进行哈希处理) 函数适用。

如果表的键是 gchar * 我会使用 g_str_hashg_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() and g_direct_equal() functions applies.

If the key of the table is gchar * I'd use g_str_hash and g_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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文