2009-03-31 8 views
3

C 프로그램에서 GLib의 해시 테이블 구현을 사용하려고합니다. 단지 지금은 으로 실험하고 있습니다.GLib 해시 테이블 루프 문제

#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; 
} 

어떻게 든 내 테스트 코드를 반복 올바르게하지만 루프에서 항상 마지막 키와 마지막 값 쌍을 반환하고 항상 동일합니다 : 나는 테스트를 위해 다음 코드 조각을 썼다. 여기에 어떤 문제가 있습니까? 위의 코드는 형식 그대로 실행되지 않을 수 있습니다. 나는 지금 내가하려고하는 것에 대해 명확한 생각을주기 위해 일부 부분을 복사하여 붙여 넣었다.

답변

4

key, a 신고서에 오류가 있습니다. 항상 같은 포인터를 해시 테이블에 넣습니다. 시도 :

#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; 
} 
9

삽입 코드가 깨졌습니다. 메모리를 한 번만 할당하고 많은 삽입 작업을 수행하면서 각각의 할당 된 위치에 저장된 값을 증가시킵니다.

해시 테이블은 포인터를 저장하므로 결국 각 키가 동일한 포인터와 연결됩니다.

또한 일관성을 위해 glib에 g_malloc()을 사용해야합니다.

그리고 항상 유형 대신 객체에 sizeof을 사용하는 것이 좋습니다. 그런 식으로 자신을 위험한 방식으로 반복하지 마십시오. 그래서, 대신 나중에 유형을 변경하는 경우에도

guint32 *a; 

    a = g_malloc(sizeof (guint32)); 

사용

a = g_malloc(sizeof *a); 

당신은 항상에서 어떤 a 포인트를 저장할 수있는 충분한 공간을 할당 할 수 있도록 당신이 종속성을 "잠글"이 방법의 .

또한 모든 캐스팅을주의 깊게 살펴야합니다. 비정상적인 포인터를 gpointer으로 전송하는 것은 주저하는 프로그래머의 표시입니다. glib를 사용하면 gpointer은 단지 void *의 동의어이므로 캐스트가 필요하지 않습니다. 코드에 코드를 추가하기 만하면 읽기가 더 어려워집니다.

+0

고맙습니다. – systemsfault

+1

sizeof (C99 6.5.3)의 문법은'sizeof unary-expression | sizeof (type-name)'이며,이 예제에서는 유형 이름 만 사용되므로 여기에 괄호가 필요합니다. –

+0

나는 glib을 오랫동안 사용해 왔으며, 이런 것들을 찾아내는 데 도움이됩니다. :) – unwind