You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C语言实现哈希表字典重哈希功能运行异常,求错误排查

代码存在的核心错误

  • 错误1:新分配的桶数组未初始化
    malloc申请的new_bins内存是未初始化的垃圾值,每个桶的初始指针不是NULL,后续遍历新桶链表时会触发野指针访问。需要在malloc后立刻把所有桶指针初始化为NULL。

  • 错误2:节点没有实际挂载到新桶链表上
    你定义的cur2是栈上的局部变量,cur2 = cur只是修改了局部变量的值,完全没有修改新桶new_bins[new_idx]的指向,相当于所有节点都没有被挂载到新数组上,重哈希后新桶数组全是空的,之前的节点全部内存泄漏。
    正确的做法是直接把节点头插或者尾插到新桶的链表上,头插效率更高不需要遍历到链表尾部:

// 头插法挂载节点,不需要遍历链表
cur->next = new_bins[new_idx];
new_bins[new_idx] = cur;
  • 错误3:旧链表遍历逻辑错误
    你在遍历旧桶链表时直接用cur = cur->next,但上面的头插操作会修改cur->next的指向,导致旧链表后续节点无法被正确遍历。需要在处理当前节点前先保存下一个节点的地址:
struct list *cur, *next;
for(cur=D->bins[idx]; cur; cur=next) {
    next = cur->next; // 提前保存下一个节点地址
    // 后续处理cur的逻辑
}
  • 错误4:缺少malloc失败的容错处理
    如果new_bins = malloc(...)分配失败返回NULL,后续操作会直接崩溃,需要加判空逻辑,分配失败时返回错误码。

修正后的重哈希函数参考

static int dict_rehash(struct dict *D)
{
    int idx;
    int new_idx;
    unsigned int new_nbins; 
    struct list **new_bins;
    struct list *cur, *next;

#if DEBUG
    dict_debug_bin_fill(D);
    fprintf(stderr, "Rehashing...\n");
    sleep(3);
#endif

    new_nbins = D->nbins * 2; 
    new_bins = malloc(new_nbins * sizeof(*D->bins));
    if (new_bins == NULL) {
        return -1; // 内存分配失败返回错误
    }
    // 初始化新桶所有指针为NULL
    for (int i = 0; i < new_nbins; i++) {
        new_bins[i] = NULL;
    }

    for (idx = 0; idx < D->nbins; idx++) {
        // 提前保存next指针,避免修改cur->next后断链
        for(cur = D->bins[idx]; cur; cur = next) {
            next = cur->next;
            new_idx = cur->hash % new_nbins;
            // 头插法将节点挂载到新桶
            cur->next = new_bins[new_idx];
            new_bins[new_idx] = cur;
        }
    }

    free(D->bins);
    D->bins = new_bins;
    D->nbins = new_nbins;

    return 0;
}

内容的提问来源于stack exchange,提问作者Azeem Akram

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.18 07:54:07