Pregunta

Voy a usar GLib aplicación tabla hash 's en un programa de C y justo por ahora Estoy experimentando con ella. Escribí el siguiente fragmento de código para la prueba:

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

 int main(){
 // Some codes and declerations here
 GHashTable *g_hash_table;
 uint32_t *a;
 a=(uint32_t *)malloc(sizeof(uint32_t));
 if(a==NULL){
    printf("Not Enough Mem For a\n");
    return 1;
 }
 *a=1123231;

 uint32_t* key;
 key=(uint32_t *)malloc(sizeof(uint32_t));
 if(key==NULL){
     printf("Not Enough Mem For key\n");
     return 1;
 }
 *key=122312312;
 int i;
 g_hash_table=g_hash_table_new(g_int_hash, g_int_equal);
 for(i=0;i<TABLE_SIZE;i++){
     *key+=1;
     *a+=1;
     g_hash_table_insert(g_hash_table,(gpointer)key,(gpointer)a);
     uint32_t *x=(uint32_t *)g_hash_table_lookup(g_hash_table,key);
     printf("Counter:%d,  %u\n",i,*x);
 }

GHashTableIter iter;
g_hash_table_iter_init(&iter,g_hash_table);
int size=g_hash_table_size(g_hash_table);
printf("First size: %d\n",size);
uint32_t *val;
uint32_t *key_;
int counter=0;

// My problem is in the following loop it 
// always returns the same and the last key value pair
 while(g_hash_table_iter_next(&iter,(gpointer*)(void*)&key_,(gpointer*)(void*)&val)){
     counter++;
     printf("%u %u\n",(uint32_t)*key_,(uint32_t)*val);
     printf("Counter: %d\n",counter);
 }
 //Some more code here        
    return 0;
}

De alguna manera mi examen itera código correctamente, pero en el bucle siempre devuelve la última llave y pares del último valor y siempre es el mismo. ¿Cuál es el problema aquí? El código anterior puede funcionar con su formato como es. He copiado y pegado algunas partes para dar una idea clara acerca de lo que estoy tratando de hacer.

¿Fue útil?

Solución

Hay un error en key, declaraciones a. Siempre se pone el mismo puntero en la tabla hash. Proveedores:

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

#define TABLE_SIZE 12

int main() {
    // Some codes and declarations here
    GHashTable *g_hash_table;
    int i;

    g_hash_table = g_hash_table_new(g_int_hash, g_int_equal);
    for (i=0; i<TABLE_SIZE; i++)
    {
        uint32_t* key = (uint32_t *)malloc(sizeof(uint32_t));
        uint32_t* a = (uint32_t *)malloc(sizeof(uint32_t));
        *key = i;
        *a   = i+10;
        g_hash_table_insert(g_hash_table, (gpointer)key, (gpointer)a);
        uint32_t *x = (uint32_t *)g_hash_table_lookup(g_hash_table,key);
        printf("key: %d -->  %u\n", *key ,*x);
    }

    GHashTableIter iter;
    int size=g_hash_table_size(g_hash_table);
    printf("First size: %d\n", size);

    uint32_t *val;
    uint32_t *key_;

    // My problem is in the following loop
    // it always returns the same and the last key value pair

    g_hash_table_iter_init (&iter, g_hash_table);
    while (g_hash_table_iter_next (&iter, (gpointer) &key_, (gpointer) &val))
    {
        printf("key %u ---> %u\n", (uint32_t)*key_, (uint32_t)*val);
    }

    // TODO: free keys
    return 0;
}

Otros consejos

Creo que el código de inserción está roto. Sólo estás asignación de memoria una vez, pero luego haciendo muchas inserciones, incrementando el valor almacenado en la ubicación asignada única entre cada uno.

El hash tabla almacena el puntero, por lo que acabará asociando cada tecla con el mismo puntero.

Además, probablemente tendrá que usar g_malloc() con mucha labia, para mantener la coherencia.

Y siempre recomiendo el uso de sizeof en objetos más que en sus tipos; de esa manera usted no repita a sí mismo de una manera tan peligroso. Así, en lugar de

  guint32 *a;

  a = g_malloc(sizeof (guint32));

uso

  a = g_malloc(sizeof *a);

De este modo, para "cerrar" la dependencia, por lo que siempre asigna suficiente espacio para almacenar puntos en lo a, incluso si posteriormente cambia el tipo.

Además, usted debe tomar una mirada a cada lance que haces. Fundición cualquier puntero no constante a gpointer es un signo de un programador vacilante. Con mucha labia, gpointer es simplemente un sinónimo de void *, por lo que nunca se necesita que el elenco. Que sólo añade, hay cosas que a su código, por lo que es más difícil de leer.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top