c语言中GHashTable的使用

news/2025/1/8 1:17:03/

前言:最近在c代码中需要用到键值对的存储,由于没有map,需要自己实现或者使用库函数,g_hash_table_new是GLib中的库函数,但使用起来会有很多坑,记录一下

构建hash表g_hash_table_new

GHashTable* g_hash_table_new(GHashFunc hash_func, GCompareFunc key_equal_func);

hash_func(GHashFunc 类型)
这是一个哈希函数,用于根据键的值计算哈希码。哈希函数应该返回一个整数,这个整数将作为键的哈希值
常见的有
需要注意的是,存储都是以指针类型存储,存储的是个地址,查找时候也会根据传入的地址查找

guint g_str_hash(const gchar *str);
guint g_int_hash(const gint *value);
guint g_double_hash(const gdouble *value);

key_equal_func(GCompareFunc 类型)
这是一个比较函数,用于比较两个键是否相等。它应该返回一个整数值,如果返回值为 0,表示两个键相等;如果返回值为非零值,则表示键不相等。
常见的有

gboolean g_int_equal(const gint *a, const gint *b);
gboolean g_str_equal(const gchar *a, const gchar *b);
gboolean g_double_equal(const gdouble *a, const gdouble *b);

hash插入g_hash_table_insert

g_hash_table_insert() 只会替换旧的值,而不会替换键。如果键已经存在,它会更新与该键相关联的值;如果键不存在,它会插入新的键值对

gboolean g_hash_table_insert(GHashTable *hash_table, gconstpointer key, gpointer value);

hash查找g_hash_table_lookup

如果哈希表中存在与给定键匹配的键值对,g_hash_table_lookup() 返回指向该值的指针。
如果哈希表中没有与给定键匹配的键值对,g_hash_table_lookup() 返回 NULL

gpointer g_hash_table_lookup(GHashTable *hash_table, gconstpointer key);

使用过程中的问题

我有这样一组数据

Physical Curve(1) = {2, 6, 7, 11, 3, 4, 9, 11};
Physical Curve(2) = {5, 1};
Physical Curve(3) = {10};

在读取的时候我希望他能插入到hash表以便我后续对{}中的内容进行枚举定义,期望的key->value是

2->1
6->1
...
5->2
...
10->3

在插入的过程中我这样插入

key = 2;
value = 1;
g_hash_table_insert(physical_curve_table, &key, &value);

结果发现我在查找的时候使用对应的key找不到value的值

int id = 2;
g_hash_table_lookup(physical_curve_table, &id);

原因:在插入的过程中由于我的key和value是局部遍历,在我走到查询的时候已经被销毁(推测是地址被重新使用)导致找不到对应的value

解决方法:插入的时候为key,value开辟空间,但是查找并不需要,还是按照原来的方法(应该是比对的之前存储地址对应的值和我当前的值,没有深究,问题得到解决)
可以正常存储并查找<int,int>类型的键值对

key = 2;
value = 1;
int *key_ptr = g_malloc(sizeof(int));
*key_ptr = key;
int *value_ptr = g_malloc(sizeof(int));
*value_ptr = value;g_hash_table_insert(plane_surface_table, key_ptr, value_ptr);
int id = 2;
g_hash_table_lookup(physical_curve_table, &id);

http://www.ppmy.cn/news/1561421.html

相关文章

使用 Spring 的 事件发布和监听机制,结合异步执行 的功能达到方法异步执行

设计思路 定义事件类&#xff1a;首先&#xff0c;我们需要定义一个事件类&#xff0c;该类将传递必要的参数&#xff08;例如&#xff0c;null, “API”, Trade.getId()&#xff09;。 异步事件监听器&#xff1a;使用 Spring 的 Async 注解将监听器设置为异步运行&#xff0…

6 网络编程

基本概念扫盲 为什么需要计算机网络 如下图所示,A、B、C三个不同地域的主机要想进行通信不是凭空就可以通信的,而是需要基于互联网进行互相连接、通信。 为什么需要协议 如下图所示,红和蓝是联合攻打绿,它们以烽火为信号出动攻打绿,那么这时候就需要一个约定,比如红先…

【C++数据结构——图】最短路径(头歌教学实验平台习题) 【合集】

目录&#x1f60b; 任务描述 相关知识 带权有向图 Dijkstra算法 测试说明 通关代码 测试结果 任务描述 本关任务&#xff1a;编写一个程序&#xff0c;利用Dijkstra算法&#xff0c;实现带权有向图的最短路径。 相关知识 为了完成本关任务&#xff0c;你需要掌握&#x…

(五)善用背景设定,让 ChatGPT 回答更精准

&#x1f4e2;&#x1f4e2;&#x1f4e2; 大家好&#xff0c;我是云楼Yunlord&#xff0c;CSDN博客之星人工智能领域前三名&#xff0c;多年人工智能学习工作经验&#xff0c;一位兴趣稀奇古怪的【人工智能领域博主】&#xff01;&#xff01;&#xff01;&#x1f61c;&#…

最新MySQL面试题(2025超详细版)

2025最新超详细MySQL面试题 文章目录 2025最新超详细MySQL面试题[toc]一、 SQL 和基本操作1. SQL的执行顺序2. 如何优化MySQL查询3. 常用的聚合函数4. 数据库事务5. 事务的四大特性(ACID)6. 视图7. MySQL中使用LIMIT子句进行分页8. MySQL中使用变量和用户定义的函数9. MySQL中的…

Flink系列知识讲解之:深入了解 Flink 的网络协议栈

Flink系列知识之&#xff1a;深入了解 Flink 的网络协议栈 Flink 的网络协议栈是组成 flink-runtime 模块的核心组件之一&#xff0c;也是每个 Flink 任务的核心。它连接着来自所有任务管理器的各个工作单元&#xff08;子任务&#xff09;。这是流数据流过的地方&#xff0c;…

ThreadLocal` 的工作原理

ThreadLocal 的工作原理&#xff1a; ThreadLocal 是 Java 提供的一个类&#xff0c;它用于为每个线程提供独立的变量副本。也就是说&#xff0c;多个线程访问同一个 ThreadLocal 变量时&#xff0c;每个线程看到的值都是不同的&#xff0c;相互隔离&#xff0c;互不干扰。 T…

【华为OD-E卷 - 观看文艺汇演问题 100分(python、java、c++、js、c)】

【华为OD-E卷 - 观看文艺汇演问题 100分&#xff08;python、java、c、js、c&#xff09;】 题目 为了庆祝中国共产党成立 100 周年&#xff0c;某公园将举行多场文艺表演&#xff0c;很多演出都是同时进行。 一个人只能同时观看一场演出&#xff0c;且不能迟到早退。 由于演…