2015-11-13 70 views
1

我想編譯一個示例程序來使用lhash。我看不到有關lhash的好教程。所以,我理解lhash的唯一方法是使用lhash linux手冊頁。這是我正在嘗試的例子。但是,我在執行lh_insert時遇到了崩潰。我無能爲力,爲何會發生。lhsh在C中的lh_insert崩潰 - Linux?

/** In order to compile this program do the following **/ 

/** gcc lhastEx.c -lcrypto -o lhastEx.out **/ 

/** Install the openssl dev library on ubuntu by -- sudo apt-get install libssl-dev **/ 
/*** This is needed for library hash -- basically open ssl ones **/ 
#include <openssl/lhash.h> 

/** Hash table -- just like maps in C++ i.e. QMAP -- it needs a key and the value **/ 

/*I have got a prints to check the flow */ 
#define __DBG (1) 

static void dbgMsg(const char *msg) 
{ 
#if __DBG 
    printf("%s",msg); 
#endif 
} 


static int cmpFunc(const void *src, const void *dest) 
{ 
    dbgMsg("cmpFunc called..\r\n"); 

    const int *obj1 = src; 
    const int *obj2 = dest; 

    return memcmp(obj1, obj2, sizeof(int)); 

} 

static unsigned long keyHash(const void *entry) 
{ 
    unsigned long int hash = 0; 
    const int *val = entry; 
    dbgMsg("keyHash method invoked\r\n"); 

    hash |= *(val); 

    return hash; 
} 

int main(int argc, char *argv[]) 
{ 
    int *hashKey2 = malloc(sizeof(int)); 

    int *hashKey3 = malloc(sizeof(int)); 

    int *hashKey1 = malloc(sizeof(int)); 

    *hashKey1 = 10; 
    *hashKey2 = 20; 
    *hashKey3 = 30; 

    /* we can make a function to generate this key unique **/ 
    /** Ideally, this 1 should be a unique hash value **/ 

    /************** Created the hash table now -- I see this as equivalent to the map in C++ or QtMap **/ 
    LHASH_OF(int) *hashtable = lh_new(keyHash, cmpFunc); 
    /*** add a new entry now **/ 


    lh_insert(hashtable, hashKey2); 


    return 0; 

} 

回答

1

的LHASH API可用於(有點)類似於STACK API。此外,還有OpenSSL源代碼可以幫助您瞭解它。例如,參見crypto/err/err.c,其使用ERR_STRING_DATA的散列表並參見lhash.hsafestack.h以獲得宏定義。

最安全的方法是爲您的表定義強類型函數。在這種情況下,一個關鍵的方面就是散列表中的元素必須是結構類型。通過使用帶有單個int字段的結構,請參閱下面的代碼,瞭解它如何用於整數哈希表。

#include <openssl/lhash.h> 
#include <string.h> 

#define __DBG (1) 

static void dbgMsg(const char *msg) 
{ 
#if __DBG 
    printf("%s", msg); 
#endif 
} 

typedef struct int_value_st { 
    int value; 
} INT_VALUE; 

static int int_value_cmp(const INT_VALUE *a, const INT_VALUE *b) 
{ 
    dbgMsg("cmpFunc called..\r\n"); 
    return a->value - b->value; 
} 
static IMPLEMENT_LHASH_COMP_FN(int_value, INT_VALUE); 

static unsigned long int_value_hash(const INT_VALUE *entry) 
{ 
    unsigned long int hash = 0; 
    dbgMsg("keyHash method invoked\r\n"); 

    hash |= entry->value; 

    return hash; 
} 
static IMPLEMENT_LHASH_HASH_FN(int_value, INT_VALUE); 

/* See stack/safestack.h for a complete list of the possible #defines */ 
#define lh_INT_VALUE_new() LHM_lh_new(INT_VALUE,int_value) 
#define lh_INT_VALUE_insert(lh,inst) LHM_lh_insert(INT_VALUE,lh,inst) 
#define lh_INT_VALUE_retrieve(lh,inst) LHM_lh_retrieve(INT_VALUE,lh,inst) 
#define lh_INT_VALUE_delete(lh,inst) LHM_lh_delete(INT_VALUE,lh,inst) 
#define lh_INT_VALUE_free(lh) LHM_lh_free(INT_VALUE,lh) 

int LHashTest(void) 
{ 
    DECLARE_LHASH_OF(INT_VALUE); 

    INT_VALUE *hashKey1 = OPENSSL_malloc(sizeof(*hashKey1)); 
    INT_VALUE *hashKey2 = OPENSSL_malloc(sizeof(*hashKey2)); 
    INT_VALUE *hashKey3 = OPENSSL_malloc(sizeof(*hashKey3)); 
    INT_VALUE *hashKeyFound = NULL; 

    hashKey1->value = 10; 
    hashKey2->value = 20; 
    hashKey3->value = 30; 

    LHASH_OF(INT_VALUE) *hashtable = NULL; 
    hashtable = lh_INT_VALUE_new(); 
    lh_INT_VALUE_insert(hashtable, hashKey1); 
    lh_INT_VALUE_insert(hashtable, hashKey2); 
    lh_INT_VALUE_insert(hashtable, hashKey3); 

    /* Should find result */ 
    hashKeyFound = lh_INT_VALUE_retrieve(hashtable, hashKey2); 
    lh_INT_VALUE_delete(hashtable, hashKeyFound); 
    /* Should not find result */ 
    hashKeyFound = lh_INT_VALUE_retrieve(hashtable, hashKey2); 

    /* OPENSSL_free()s all elements */ 
    lh_INT_VALUE_free(hashtable); 

    return 1; 
} 

順便說一句,它看起來像你忽略了一些編譯器警告......通常不是一件好事。

0

我發現這是由於open-ssl的後向不兼容版本造成的。這是更正 -

_LHASH *hashtable = lh_new(keyHash, cmpFunc); 

它只是工作得很好。這是現在的整個代碼。這可能會幫助一些新人試圖用他的手段。雖然,我認爲C++提供了更加清潔的散列方式,而不是C。我不喜歡這個庫。但是,它用於舊項目。

/** In order to compile this program do the following **/ 

/** gcc lhastEx.c -lcrypto -o lhastEx.out **/ 

/** Install the openssl dev library on ubuntu by -- sudo apt-get install libssl-dev **/ 
/*** This is needed for library hash -- basically open ssl ones **/ 
#include <openssl/lhash.h> 

/** Hash table -- just like maps in C++ i.e. QMAP -- it needs a key and the value **/ 

/*I have got a prints to check the flow */ 
#define __DBG (1) 

static void dbgMsg(const char *msg) 
{ 
#if __DBG 
    printf("%s",msg); 
#endif 
} 


static int cmpFunc(const void *src, const void *dest) 
{ 
    dbgMsg("cmpFunc called..\r\n"); 

    const int *obj1 = src; 
    const int *obj2 = dest; 

    return memcmp(obj1, obj2, sizeof(int)); 

} 

static unsigned long keyHash(const void *entry) 
{ 
    unsigned long int hash = 0; 
    const int *val = entry; 
    dbgMsg("keyHash method invoked\r\n"); 

    hash |= *(val); 

    return hash; 
} 

int main(int argc, char *argv[]) 
{ 
    int inputBucket = 0; 
    int *hashKey2 = malloc(sizeof(int)); 

    int *hashKey3 = malloc(sizeof(int)); 

    int *hashKey1 = malloc(sizeof(int)); 

    *hashKey1 = 10; 
    *hashKey2 = 20; 
    *hashKey3 = 30; 

    int *ptrInputBucket = &inputBucket; 

    /* we can make a function to generate this key unique **/ 
    /** Ideally, this 1 should be a unique hash value **/ 

    /************** Created the hash table now -- I see this as equivalent to the map in C++ or QtMap **/ 
    _LHASH *hashtable = lh_new(keyHash, cmpFunc); 
    /*** add a new entry now **/ 

    lh_insert(hashtable, hashKey2); 
    lh_insert(hashtable, hashKey3); 

    /** now retrieve the data **/ 
    ptrInputBucket = lh_retrieve(hashtable, hashKey2); 

    if(ptrInputBucket != NULL) 
    { 
     printf("The value retrieve from Hash Table is %d\r\n", *ptrInputBucket); 
    } 
    return 0; 

} 
+0

很高興看到你,你找到了一種方法。請注意,這存在與此相關的風險:您基本上使用散列表的「無類型」版本。這意味着編譯器不會阻止您將錯誤的類型變量插入到表中。如果你有興趣,如果你想做一個強類型的版本,我已經包含了一個答案。 –