2014-03-23 2 views
0

Я работаю над программой, в которой используется хэш-таблица Glib. Когда программа запускается, она считывает файл и заполняет хэш-таблицу на основе этих данных. Когда программа запускается, пользователь дает свои данные, а код проверяет наличие ключа - если да, обновите значение, если нет, вставьте новый ключ.Glib hash table - key не существует

Вот пример:

// fill hash with data's 
    datastore = g_hash_table_new(g_str_hash, g_str_equal); 
    while (fgets(inputbuffer, 90, fp) != NULL) { 
     parse_utypeline(inputbuffer, udatakey, &udataidx); // parse line, store fields in udatakey and udataidx 
     utype_inc(udatakey, udataidx); // push to hash 
     total++; 
    } 


    // another part of code, find value of key 
    nrofutype = utype_get(utypereclist.udatakey, udatainx); 

// implemented functions 
int utype_inc(char udatakey[15], int udata) { 

    t_utype_rec_udatas *utype_rec_udatas; 
    int i; 
    gboolean gb; 
    GList * hkeys = NULL; 
    int gi; 

    syslog(LOG_DEBUG, "utype store: %p", datastore); 
    gb = g_hash_table_contains(datastore, udatakey); 

    if (gb == 0) { 
     utype_rec_udatas = g_malloc0(sizeof *utype_rec_udatas); 
     for(i=0; i<10; i++) { 
      /* 
      * every item has derived like this: 
      * typedef unsigned char t_utype_rec_udatas[10]; 
      * t_utype_rec_udatas *utype_rec_udatas; 
      */ 
      (*utype_rec_udatas)[i] = 0; 
     } 
     g_hash_table_insert(datastore, udatakey, utype_rec_udatas); 
    } 
    else { 
     utype_rec_udatas = g_hash_table_lookup(datastore, udatakey); 
    } 
    (*utype_rec_udatas)[udata]++; 

    gb = g_hash_table_contains(datastore, udatakey); 
    if (gb == 0) { 
     return -1; 
    } 
    else { 
     utype_rec_udatas = g_hash_table_lookup(datastore, udatakey); 
     return (*utype_rec_udatas)[udata]; 
    } 

} 

int utype_get(char udatakey[15], int udata) { 
    t_utype_rec_udatas *utype_rec_udatas; 
    gboolean gb; 

    if (datastore == NULL) { 
     syslog(LOG_DEBUG, "store doesn't exists"); 
     return -1; 
    } 

    gb = g_hash_table_contains(datastore, udatakey); 
    if (gb == 0) { 
     return -1; 
    } 
    else { 
     utype_rec_udatas = g_hash_table_lookup(datastore, udatakey); 
     return (*utype_rec_udatas)[udata]; 
    } 
} 

Проблема состоит в том случае, если код вызывает utype_get() в последующих частях, ключ не существует (которая существует, то точно). Если я положу строки syslog и попытаюсь поймать некоторые данные, я вижу, что адрес хеш-таблицы одинаковый в каждый момент времени. Если функция utype_inc() регистрирует udatakey, она кажется корректной в syslog (я зарегистрировал данные с g_hash_table_get_keys(datastore);). Но если utype_get() вызвал, g_hash_table_get_keys(datastore); дает некоторую очень подробную информацию ... от такой же магазин! Вот это Syslog линии:

Mar 23 18:13:09 basil myprog: udata store: 0x2371400 
Mar 23 18:13:09 basil myprog: new udatakey: 'ABCD', udataidx: 0 
Mar 23 18:13:09 basil myprog: store value: 1 
Mar 23 18:13:09 basil myprog: 0. key: 'ABCD' 
Mar 23 18:13:09 basil myprog: size of hash: 1 

Mar 23 18:13:13 basil myprog: udata_get - udatakey: '', udataidx: 0 
Mar 23 18:13:13 basil myprog: udata_get - size of hash: 1 
Mar 23 18:13:13 basil myprog: udata_get - 0. key: '#020#001' 
Mar 23 18:13:13 basil myprog: udata_get - udatakey doesn't exists in store: 0x2371400 

Я не знаю, что # 020 # 001 (я знаю, что это возможно пространство, и 0x01), но почему?

Любой помогает радушны,

благодарит:

а.

+0

Что говорит valgrind? Похоже на повреждение памяти – CMoi

+0

Я не эксперт valgrind, вот соответствующий вывод (так, я думаю, что это соответствующая часть): == 10434 == Неверный просмотр размера 1 == 10434 == на 0x4C2E4C1: strcmp (в /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) == 10434 == by 0x4E6C9B8: g_str_equal (в /lib/x86_64-linux-gnu/libglib-2.0.so.0.3800. 1) == 10434 == by 0x4E6C3CA: g_hash_table_contains (в /lib/x86_64-linux-gnu/libglib-2.0.so.0.3800.1) == 10434 == by 0x423AA3: utype_get (utypeutil.c: 119) ... == 10434 == Адрес 0x7fefffc30 не является stack'd, malloc'd или (недавно) free'd – airween

+0

Первый шаг кода (заполнить хэш-таблицу) выполняется в другом потоке, чем второй (get , и вставить новое) - может ли это эта проблема? Хэш-таблица (datastore = g_hash_table_new (g_str_hash, g_str_equal);) была создана в этом потоке ... – airween

ответ

0

Решение было:

char datakeys[BIGNR][15]; 

// implemented functions 
int utype_inc(char udatakey[15], int udata) { 
... 
    gb = g_hash_table_contains(datastore, udatakey); 

    if (gb == 0) { 
     utype_rec_udatas = g_malloc0(sizeof *utype_rec_udatas); 
     for(i=0; i<10; i++) { 
      /* 
      * every item has derived like this: 
      * typedef unsigned char t_utype_rec_udatas[10]; 
      * t_utype_rec_udatas *utype_rec_udatas; 
      */ 
      (*utype_rec_udatas)[i] = 0; 
     } 
     gi = g_hash_table_size(datastore_store); 
     strncpy(datakeys[gi], udatakey, strlen(udatakey)); 
     g_hash_table_insert(datastore, datakeys[gi], utype_rec_udatas); 
    } 
... 
... 

Спасибо за помощь,

а.