Поведение хеш-таблицы с использованием glib - PullRequest
0 голосов
/ 30 мая 2011

Я хочу обновить громкость каждого @IP.Так, например, после каждых 5 с я добавляю V (i) каждого @IP (i).Хорошо, теперь хеш-таблица работает нормально, она обновляется через каждые T секунд .Но проблема в том, что после определенного периода Я обнаружил, что иногда один и тот же IP-адрес повторяется дважды или даже много раз в хэш-таблице .Так что, когда я закрываю процесс, я вижу, что один и тот же @IP повторяется слишком много раз.Это похоже на проблему с хэш-таблицей или чем-то в этом роде.

Вот код эта функция "update_hashTable ()" настолько важна, что она вызывается каждые X секунд На самом деле я подозреваю утечку памяти ... потому что я всегда вызываю malloc дляIP @.но он продолжает работать ... любая идея ???

int update_hashTable( ... ) {

u_int32_t *a;

... //declarations

struct pf_addr *as;


as = ks->addr[0];

a = (u_int32_t*)malloc(sizeof(u_int32_t));

*a = ntohl(as->addr32[0]);

sz = value; // no matter it is... an int for example

if (ReturnValue=(u_int32_t)g_hash_table_lookup(hashtable, a)) {

  ReturnValue +=sz;
  g_hash_table_insert(hashtable, (gpointer)a, gpointer)ReturnValue);
}
else {
  g_hash_table_insert(hashtable, (gpointer)a, (gpointer)sz);
}

1 Ответ

3 голосов
/ 31 мая 2011

Действительно, у вас, похоже, утечка памяти, но это не ваша проблема. Проблема в том, что истинный путь вашего оператора if просто вставляет второе значение, связанное с тем же ключом, а это не то, что вам нужно.

Типичным шаблоном для этого алгоритма проверки, если существует, и алгоритмом приращения обычно является что-то вроде

gpointer val = g_hash_table_lookup(hash_table, key);
if (val == NULL) {
    val = g_malloc0(...);
    g_hash_table_insert(hash_table, key, val);
}
*val = /* something */;

Важно помнить, что, получив указатель на значение, связанное с каким-либо ключом, вы можете просто изменить его напрямую.

Если этот код будет выполняться несколькими потоками параллельно, тогда весь блок должен быть защищен мьютексом, возможно, с помощью GMutex: http://developer.gnome.org/glib/2.28/glib-Threads.html

gcc предоставляет встроенные встроенные атомарные функции, скажем, для атомарного увеличения значения, см. http://gcc.gnu.org/onlinedocs/gcc/Atomic-Builtins.html

...