uthash使用示例

1)字符串在结构体中

一个字符串做键的哈希(字符串在结构体中):uthash_exer1.c

#include <string.h>  /* strcpy */
#include <stdlib.h>  /* malloc */
#include <stdio.h>   /* printf */
#include "uthash.h"

struct my_struct {
    char name[10];             /* 键(字符串在这个结构体内部) */
    int id;
    UT_hash_handle hh;         /* 使得这结构体可哈希 */
};


int main(int argc, char *argv[]) {
    const char *names[] = { "joe", "bob", "betty", NULL };
    struct my_struct *s, *tmp;
    struct my_struct *users = NULL; //用作哈希表头

    //分配一个结构体,内部name成员存储传入的字符串
    //并且使用结构体name字段将结构体存入以s为表头的哈希表
    for (int i = 0; names[i]; ++i) {
        s = (struct my_struct *)malloc(sizeof *s);
        strcpy(s->name, names[i]);
        s->id = i;
        HASH_ADD_STR(users, name, s);
    }

    // 根据传入字符串为键,从哈希表中查找结构体,如果存在,输出这个结构体的id成员变量
    for (int i = 0; names[i]; i++){
        HASH_FIND_STR(users, names[i], s);
        if (s) printf("%s's id is %d\n", names[i] ,s->id);
    }

    /* 从哈希表中取出结构体,并且从哈希表中删除,然后释放这个结构体 */
    HASH_ITER(hh, users, s, tmp) {
      HASH_DEL(users, s);
      free(s);
    }
    return 0;
}

编译以上程序,进行测试:

[blctrl@rockygu uthash]$ gcc uthash_exer1.c -o uthash_exer1
[blctrl@rockygu uthash]$ ./uthash_exer1
joe's id is 0
bob's id is 1
betty's id is 2

2)在结构体中字符串指针

现在,这是一个相同示例,但使用了一个char *键替换char []。

一个以字符串为键的哈希(结构体中指字符指针)

#include <string.h>  /* strcpy */
#include <stdlib.h>  /* malloc */
#include <stdio.h>   /* printf */
#include "uthash.h"

struct my_struct {
    const char *name;          /* 键:内容在结构体外 */
    int id;
    UT_hash_handle hh;         /* 使得这个结构体可哈希  */
};


int main(int argc, char *argv[]) {
    const char *names[] = { "joe", "bob", "betty", NULL };
    struct my_struct *s, *tmp;
    struct my_struct *users = NULL; //哈希表头

    for (int i = 0; names[i]; ++i) {
        s = (struct my_struct *)malloc(sizeof *s);
        s->name = names[i]; //结构体的name成员指向一个字符串
        s->id = i;
        // 结构体可哈希标识成员,哈希表头,作为键的成员变量,成员变量指向字符串的长度,要放入哈希表的结构体
        HASH_ADD_KEYPTR(hh, users, s->name, strlen(s->name), s);
    }

    for (int i = 0; names[i]; i++){
        HASH_FIND_STR(users, names[i], s);
        if (s) printf("%s's id is %d\n", names[i], s->id);
    }
    /* 释放哈希表,并且释放分配的结构体*/
    HASH_ITER(hh, users, s, tmp) {
      HASH_DEL(users, s);
      free(s);
    }
    return 0;
}

编译以上程序,进行测试:

[blctrl@rockygu uthash]$ gcc uthash_exer2.c -o uthash_exer2
[blctrl@rockygu uthash]$ ./uthash_exer2
joe's id is 0
bob's id is 1
betty's id is 2

3) 指针键

键可以是一个指针。

#include <stdio.h>
#include <stdlib.h>
#include "uthash.h"

typedef struct {
  void *key;
  int i;
  UT_hash_handle hh;
} el_t;

el_t *hash = NULL;  //哈希表表头
char *someaddr = "Hello World found by uthash";

int main() {
  el_t *d;
  el_t *e = (el_t *)malloc(sizeof(el_t));

  if (!e){
     return -1;
  }

  printf("address:0x%p->%s", &someaddr, someaddr);
  // 结构体成员变量key存储了一个地址
  e->key = (void*)someaddr;
  e->i = 1;

  // 以结构体字段key为键,将结构体e存入哈希表hash
  HASH_ADD_PTR(hash, key, e);
  // 以变量someaddr的地址为键,在哈希表hash中查找结构体,用d指向找到的结构体
  HASH_FIND_PTR(hash, &someaddr, d);
  if (d) {
      printf("found\n");
      printf("content:%s\n", (char *)d->key);
  }

  /* 从哈希表中删除这个结构体 */
  HASH_DEL(hash, e);
  /* 释放这个结构体 */
  free(e);
  return 0;
}

编译测试以上程序:

[blctrl@rockygu uthash]$ gcc uthash_exer3.c -o uthash_exer3
[blctrl@rockygu uthash]$ ./uthash_exer3
address:0x0x602058->Hello World found by uthashfound
content:Hello World found by uthash

4) 结构体键

你的键字段可以有任何数据类型。对于uthash,它只是一个字节序列。因而,即使一个嵌套结构体也可以被用作一个键。我们将使用一般宏HASH_ADD和HASH_FIND来演示。

在添加一个项到这个哈希或者查找一个项前,这些填充字节必须被置零。因而,在设置感兴趣成员前,总是置零整个结构体。以下示例做了这件事,键对memset的两次调用。

#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include "uthash.h"

typedef struct {
  char a;
  int b;
} record_key_t;

typedef struct {
    record_key_t key; // 作为这个结构体的键
    int i;
    char name[21];
    UT_hash_handle hh;
} record_t;

int main(int argc, char *argv[]) {
    record_key_t l;
    record_t  *p, *r, *tmp;
    record_t *records = NULL; // 作为哈希表头

    r = (record_t *)malloc(sizeof(record_t));
    // 对分配的record_t结构体填充0
    memset(r, 0, sizeof(record_t));
    // 设置键
    r->key.a = 'a';
    r->key.b = 1;
    // 设置其它成员
    r->i = 666;
    strcpy(r->name, "hello world, uthash");
    // 用结构体的key字段作为键,并出入这个键的尺寸,将结构体r放入哈希表records
    HASH_ADD(hh, records, key, sizeof(record_key_t), r);

    // 对record_key_t类型的变量填充0
    memset(&l, 0, sizeof(record_t));
    // 设置键
    l.a = 'a';
    l.b = 1;
    // 通过类型record_key_t的键,并且传入这个键的大小,查找结构体,并且用p指向这个结构体
    HASH_FIND(hh, records, &l, sizeof(record_key_t), p);

    if (p) {
        printf("found %c %d\n", p->key.a, p->key.b);
        printf("content:%d, %s\n", p->i, p->name);
    }

    HASH_ITER(hh, records, p, tmp) {
      HASH_DEL(records, p);
      free(p);
    }
    return 0;
}

编译以上程序,并进行测试:

[blctrl@rockygu uthash]$ gcc uthash_exer4.c -o uthash_exer4
[blctrl@rockygu uthash]$ ./uthash_exer4
found a 1
content:666, hello world, uthash
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
使用共享内存的方式可以让不同的进程共享同一块内存空间,从而实现进程间通信。当多个进程需要同时读取同一个哈希表时,可以使用共享内存来实现。 具体步骤如下: 1. 使用shmget函数创建共享内存,获取共享内存的标识符。 2. 使用shmat函数将共享内存附加到当前进程的地址空间中。 3. 在共享内存中创建哈希表。 4. 将要共享的数据插入到哈希表中。 5. 分离共享内存,使用shmdt函数实现。 6. 在其他进程中使用相同的标识符打开共享内存,使用shmat函数将共享内存附加到地址空间中。 7. 在共享内存中获取哈希表,并读取其中的数据。 8. 分离共享内存。 示例代码如下: ```c #include <stdio.h> #include <stdlib.h> #include <string.h> #include <stdbool.h> #include <sys/ipc.h> #include <sys/shm.h> #include "uthash.h" #define SHM_KEY 1234 #define DATA_NUM 5 typedef struct { int id; char name[20]; UT_hash_handle hh; } Data; int main() { int shmid = shmget(SHM_KEY, sizeof(Data) * DATA_NUM, IPC_CREAT | 0666); // 创建共享内存 if (shmid == -1) { perror("shmget"); return 1; } Data *data = shmat(shmid, 0, 0); // 将共享内存附加到地址空间中 memset(data, 0, sizeof(Data) * DATA_NUM); // 清空共享内存 int i; for (i = 0; i < DATA_NUM; i++) { // 向共享内存中插入数据 Data *d = &data[i]; d->id = i; sprintf(d->name, "name%d", i); HASH_ADD_INT(d->hh, id, d); } shmdt(data); // 分离共享内存 int shmid2 = shmget(SHM_KEY, sizeof(Data) * DATA_NUM, 0666); // 在另一个进程中打开共享内存 if (shmid2 == -1) { perror("shmget"); return 1; } Data *data2 = shmat(shmid2, 0, 0); // 将共享内存附加到地址空间中 Data *d; HASH_ITER(hh, data2, d, tmp) { // 读取共享内存中的哈希表 printf("id=%d, name=%s\n", d->id, d->name); } shmdt(data2); // 分离共享内存 shmctl(shmid, IPC_RMID, NULL); // 删除共享内存 return 0; } ``` 在该示例代码中,我们使用uthash库创建了一个哈希表,并将其存储在共享内存中。在另一个进程中,我们使用相同的标识符打开共享内存,并读取其中的数据。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值