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

哈希表insert_el函数报错排查:是否与free_ht实现有关?

你的insert_el错误并非由free_ht导致,但两者均存在bug

free_ht函数的问题

你的free_ht有两个致命错误:

  1. 错误释放对象:free(&ht[j]);是完全错误的——ht[j]才是你通过calloc分配的动态内存指针,&ht[j]是指针数组元素的地址,不属于动态分配的内存范围,调用free会触发未定义行为。正确写法是free(ht[j]);。
  2. 语法不完整:循环和函数都缺少闭合的},编译直接报错。

修正后的free_ht:

void free_ht(int *ht[]) {
    for (int j = 0; j < value; ++j) {
        free(ht[j]);
    }
}

insert_el函数的错误分析(各版本)

初始版本

  • 没必要用calloc分配z,直接用栈变量即可,既浪费内存又增加泄漏风险。
  • 数组长度计算逻辑完全错误:sizeof(&ht[*z])取的是指针的字节数(通常4/8),无法获取动态数组的实际长度,导致扩容彻底失效。
  • 插入逻辑混乱:遍历找0位置插入后,错误地将计数ht[z][0]设为1,丢失了真实的元素个数记录。

第一次修改

  • 改用栈变量z是正确的,但插入时仍错误地将计数重置为1,导致之前的元素计数丢失。
  • 扩容容量计算错误:忽略了计数元素占的位置,导致数组容量不足。

第二次修改

  • 直接在size位置插入元素的逻辑正确,但未更新计数ht[z][0],后续插入无法获取当前元素个数。

第三次修改(最接近正确的版本)

  • 核心错误:扩容时的数组总长度计算错误。你的数组结构是[元素个数, 元素1, 元素2,...],因此数组总长度应为元素个数 + 1。当前元素个数为size,插入后变为new_size = size + 1,此时需要的数组总长度是new_size + 1,而非你写的new_size。realloc(ht[z], new_size * sizeof(int))会导致数组容量不足,写入ht[z][size]时会触发越界访问,引发未定义行为。
  • 缺失realloc返回值检查:若内存分配失败,realloc返回NULL,直接赋值会丢失原指针,导致内存泄漏。

修正后的insert_el函数

void insert_el(int *ht[], int *x) {
    int z;
    hash_el(x, &z, value);
    
    if (ht[z][0] == 0) {
        ht[z][1] = *x;
        ht[z][0] = 1;
    } else {
        int size = ht[z][0];
        int new_size = size + 1;
        // 数组总长度 = 新元素个数 + 1(计数位)
        int *new_arr = realloc(ht[z], (new_size + 1) * sizeof(int));
        if (new_arr == NULL) {
            // 可添加内存分配失败的错误处理逻辑
            return;
        }
        ht[z] = new_arr;
        ht[z][size] = *x;
        ht[z][0] = new_size;
    }
}

内容的提问来源于stack exchange,提问作者Hannan Sandhu

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 09:10:28