C语言哈希表hash_table_apply_to_all全量赋值功能失效排查求助
问题排查结果
你代码中的问题可以分为以下几类:
1. 核心逻辑错误:空表执行遍历赋值
刚通过hash_table_create创建的哈希表为空,所有bucket的next指针均为NULL,你写的hash_table_apply_to_all函数遍历的是每个bucket的next指向的节点,空表状态下apply_fun一次都不会执行,自然不会有任何赋值效果。
2. 函数类型不匹配
你定义的apply函数指针类型是ioopm_apply_function,但hash_table_apply_to_all的第二个参数类型写的是未定义的apply_function,类型不一致会触发隐式类型转换,可能导致函数调用异常。
3. 变量定义错误
单元测试中bool result = NULL;写法错误,NULL是指针常量,赋值给bool类型会触发未定义行为,初始值会被解析为false。
4. 遍历逻辑设计问题(可选)
如果你的设计中buckets数组内的entry节点本身需要存储数据,而非仅作为哨兵节点,那当前遍历逻辑跳过了bucket的头节点,只会操作链表上的后续节点。
5. lookup函数逻辑冗余
lookup函数中next被重复赋值,逻辑冗余,在极端场景下可能触发空指针访问。
修复方案
第一步:修正单元测试逻辑
执行apply操作前先往哈希表插入测试条目,确保表非空:
void test_apply_to_all() { hash_table_t *ht = hash_table_create(); char *valtest = "a"; bool result = false; // 修正变量初始化错误 // 先插入测试条目(这里假设你已实现hash_table_insert接口) for (int i = 0; i < No_Buckets; i++) { hash_table_insert(ht, i, NULL); } hash_table_apply_to_all(ht, value_insert, valtest); for (int i = 0; i < No_Buckets; i++) { hash_table_lookup(ht, i, &result); if (!result) { break; } } CU_ASSERT_TRUE(result); hash_table_destroy(ht); }
第二步:修正函数类型匹配问题
修改hash_table_apply_to_all的参数类型,和定义的函数指针保持一致:
// 修改参数中的apply_fun类型为ioopm_apply_function void hash_table_apply_to_all(hash_table_t *ht, ioopm_apply_function apply_fun, void *arg) { for (int i = 0; i < No_Buckets; i++) { // 如果需要操作bucket本身的节点,把下一行改为 entry_t *current_entry = &ht->buckets[i]; entry_t *current_entry = (&ht->buckets[i])->next; while (current_entry != NULL) { apply_fun(current_entry->key, ¤t_entry->value, arg); current_entry = current_entry->next; } } }
第三步:优化lookup函数逻辑
char *hash_table_lookup(ioopm_hash_table_t *ht, int key, bool *result) { entry_t *tmp = find_previous_entry_for_key(&ht->buckets[key % No_Buckets], key); entry_t *next = tmp ? tmp->next : NULL; if (next && next->value) { *result = true; return next->value; } *result = false; return NULL; }
内容的提问来源于stack exchange,提问作者fireproofiii
相关产品推荐
相关产品推荐

