【问题标题】:lhash crashes on lh_insert in C - Linux?lhash 在 C - Linux 中的 lh_insert 上崩溃?
【发布时间】:2015-11-13 02:00:31
【问题描述】:

我正在尝试编译一个示例程序以使用 lhash。我看不到关于 lhash 的好教程。所以,我理解 lhash 的唯一方法是使用 lhash linux 手册页。这是我正在尝试制作的示例。但是,我在执行 lh_insert 时发生了崩溃。我不知道为什么会这样。

/** 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;

}

【问题讨论】:

    标签: c linux openssl


    【解决方案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;
    }
    

    顺便说一句,您似乎忽略了一些编译器警告……这通常不是一件好事。

    【讨论】:

      【解决方案2】:

      我发现这是由于 open-ssl 的向后不兼容版本。这是更正 -

        _LHASH *hashtable = lh_new(keyHash, cmpFunc);
      

      它工作得很好。现在是整个代码。这可能会帮助一些新人尝试使用 lhash。虽然,我认为 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;
      
      }
      

      【讨论】:

      • 很高兴看到您找到了方法。请注意,尽管这样做存在风险:您实际上使用的是散列表的“无类型”版本。这意味着编译器不会阻止您将错误类型的变量插入表中。如果您有兴趣,如果您想做一个强类型版本,我已经提供了答案。
      猜你喜欢
      • 1970-01-01
      • 2013-11-07
      • 1970-01-01
      • 2011-03-21
      • 2020-11-15
      • 2019-09-02
      • 1970-01-01
      • 2013-01-20
      • 1970-01-01
      相关资源
      最近更新 更多