g_hash_table_lookup в рекурсии - PullRequest
       1

g_hash_table_lookup в рекурсии

0 голосов
/ 10 августа 2011

Я написал следующую игрушечную программу для проверки "g_hash_table_lookup ()" внутри рекурсии:


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

void f_recursive(GHashTable *htable, int level){
    char key[] = "test_key";
    char value[] = "test_value";
    char *returned_value;

    if(level > 0){
        f_recursive(htable, level - 1);
    }
    else if(level==0){
        g_hash_table_insert(htable,&key[0],&value[0]);
    }

    returned_value = g_hash_table_lookup(htable,&key[0]);
    printf("Level=%d, Returned Value=%s\n",level, returned_value);
}

int main(int argc, char * argv[]){
    int i=3;
    GHashTable *Hash_Table;

    Hash_Table = g_hash_table_new(g_str_hash,g_str_equal);
    f_recursive(Hash_Table, i);
}

Цель этого кода - просто вызвать рекурсивную функцию, которая на каждом уровне рекурсии просматривает в хэш-таблице значение ключа, которое было вставлено только на самом низком уровне рекурсии. Я ожидаю, что на каждом уровне рекурсии я смогу восстановить значение, вставленное на самом низком уровне, и поэтому ожидаемый результат этой программы должен быть:

Level=0, Returned Value=test_value
Level=1, Returned Value=test_value
Level=2, Returned Value=test_value
Level=3, Returned Value=test_value

Однако это не то, что происходит. Вместо этого я получаю следующее:

Level=0, Returned Value=test_value
Level=1, Returned Value=([��`�
Level=2, Returned Value=(null)
Level=3, Returned Value=(null)

Буду признателен, если кто-нибудь сможет объяснить мне, почему я могу получить вставленное значение в хеш-таблице только на уровне рекурсии, где я выполняю вставку.

Спасибо!

Daniel

1 Ответ

1 голос
/ 10 августа 2011

Из тонкой инструкции :

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

Это означает, что это:

g_hash_table_insert(htable,&key[0],&value[0]);

Не копирует key или value, хеш-таблица просто хранит указатели. Однако key и value расположены в стеке:

char key[] = "test_key";
char value[] = "test_value";

Таким образом, ваши указатели &key[0] и &value[0] действительны только на время действия функции. Как только вы выйдете из своей рекурсии, у вас будет хеш-таблица, заполненная недопустимыми указателями, и это даст вам кучу мусора и неопределенного поведения.

Вы должны использовать g_hash_table_new_full с освобождающими функциями для ключей и значений, а затем дублировать свои ключи и значения при вызове g_hash_table_insert; вы можете использовать g_strdup для дублирования ключей и значений и g_free в качестве аргументов key_destroy_func и value_destroy_func для g_hash_table_new_full.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...