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

C语言哈希表存储CSV结构体数据指针问题导致无输出求解

开散列哈希表实现问题修复

核心错误点

  • 插入后立即释放节点:你将新创建的链表节点赋值给哈希表对应下标后,立刻调用free_linkedlist(d)释放了节点,导致哈希表中存储的是野指针,数据自然无法留存。
  • 未处理哈希冲突:你没有调用已实现的linkedlist_insert函数处理冲突,而是直接将新节点覆盖到哈希表对应下标,相同哈希值的旧数据会直接丢失。
  • 内存释放逻辑错误:free_linkedlist函数存在两个问题:一是循环中没有移动链表指针,会导致无限循环;二是尝试释放栈上的Pokemon结构体(temp->item指向栈数组pArray的元素,不是堆内存,不能手动释放)。
  • 哈希表打印逻辑不完整:现有print_table函数仅打印链表的头节点,无法展示冲突后插入的后续节点;且你在main函数中注释了print_table调用,自然看不到哈希表的预期输出。
  • 文件名配置问题:fopen打开的文件名为.csv,需确保你的CSV文件路径和名称匹配,否则程序会直接因打开文件失败退出。

修复后的核心代码修改

1. 修正内存释放函数

void free_linkedlist(LinkedList* list) {
    LinkedList* temp;
    while (list) {
        temp = list;
        list = list->next;
        // item指向栈数组,不需要释放
        free(temp);
    }
}

2. 修正哈希表插入逻辑(main函数循环内)

while(!feof(f) && nbPokemons < MAX_NB_POKEMON) { // 新增数组越界判断
    fetch_pokemon( f, &pArray[nbPokemons] );
    a=hash_function(pArray[nbPokemons].surname);
    // 调用链表插入函数处理冲突,不要手动分配节点、不要立即释放
    hashTable[a] = linkedlist_insert(hashTable[a], &pArray[nbPokemons]);
    printf("%d\n",a);
    print_pokemon( &pArray[nbPokemons] );
    nbPokemons++;
}
// 打开哈希表打印调用
print_table();
// 程序退出前统一释放哈希表内存
for(int i=0; i<ARRAY_SIZE; i++) {
    free_linkedlist(hashTable[i]);
}

3. 修正哈希表打印函数

void print_table(void){
    printf("Start\n");
    int i;
    for(i=0;i<ARRAY_SIZE;i++){
        if(hashTable[i] == NULL){
            printf("\t%i\t---\n",i);
        }else{
            printf("\t%i\t",i);
            LinkedList* curr = hashTable[i];
            while(curr) {
                printf("%d\t%s\t%s\t%s\t%d\t%s\t%s\t%s\t%s\t%s\n", 
                    curr->item->id, curr->item->depid, curr->item->surname,
                    curr->item->forename, curr->item->age, curr->item->type,
                    curr->item->gender, curr->item->nationality, curr->item->rel, curr->item->occ);
                curr = curr->next;
            }
        }
    }
    printf("End\n");
}

额外优化建议

  • 现有哈希函数为简单加法哈希,冲突率较高,可以优化为hash = (hash * 31 + *s) % ARRAY_SIZE降低冲突概率。
  • 可以在fetch_pokemon函数中添加字段读取合法性判断,避免CSV格式错误导致程序异常。

内容的提问来源于stack exchange,提问作者Kartik Mann

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 03:36:03