新手求助:哈希表创建时Valgrind报未初始化值相关内存问题
问题原因
- 你的哈希表初始化时为每个桶创建了一个无实际数据的哨兵节点(dummy node),仅初始化了
next指针,节点内的word字段完全未初始化 - 你的
check函数遍历哈希表桶时,会从这个哨兵节点开始读取word字段传入strcasecmp进行对比,strcasecmp内部调用tolower时读取了word中的垃圾值,触发Valgrind报错 - 报错中提到的「未初始化值来自line85的malloc」,正是指你初始化时为哨兵节点分配的内存空间
修复方案
方案1(治标,适配现有逻辑)
修改check函数的遍历起点,跳过哨兵节点,直接从table[hash(target_word)]->next开始遍历链表,不会访问到哨兵节点未初始化的word字段。
注意:该方案仍会存在哨兵节点的内存泄漏风险,你释放哈希表时需要额外释放每个桶的哨兵节点。
方案2(推荐,彻底重构逻辑,删除冗余哨兵节点)
哈希表桶不需要预先分配哨兵节点,直接初始化为空指针即可,还能简化插入逻辑:
- 替换原有初始化代码:
// 原初始化代码删除,替换为如下逻辑 for (int i = 0; i < N; i++) { table[i] = NULL; }
- 简化插入逻辑,不需要再判断链表是否为空,直接头插即可:
while (fscanf(dict, "%s", word1) != EOF) { int index = hash(word1); node *n = malloc(sizeof(node)); // 新增malloc返回值检查,避免空指针崩溃 if (n == NULL) { // 按需添加内存分配失败的处理逻辑,比如关闭文件、释放已有内存后返回false return false; } strcpy(n->word, word1); n->next = table[index]; table[index] = n; wordcounter++; }
- 对应修改
check函数的遍历逻辑,从table[hash(target_word)]开始遍历即可,不存在未初始化的哨兵节点。
内容的提问来源于stack exchange,提问作者ira994
相关产品推荐
相关产品推荐

