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

C语言链表哈希表两次调用print函数后数据丢失求助

哈希表打印后数据丢失问题排查

我实现了一个哈希表,由包含10个元素的数组构成,每个元素作为链表头节点。插入数据后第一次打印哈希表正常,但再次选择打印时,哈希表中数据全部丢失,所有值均为NULL。怀疑问题出在print函数,尝试用辅助变量遍历数组打印但没解决。

感谢任何形式的帮助!

#include <stdio.h>
#include <stdlib.h>

typedef struct no{       
    int id;   
    char name;       
    struct no *next;
}no;

void insert(no * vetor, int idInsert, char nameInsert, int pinsert){
    no *newNo = (no*)malloc(sizeof(no));
    newNo->id = idInsert;
    newNo->name = nameInsert;
    newNo->next = NULL;

    if ((vetor[pinsert]).next == NULL){ 
        (vetor[pinsert]).next = newNo;
        return;}
    newNo -> next = (vetor[pinsert].next);
    vetor[pinsert].next = newNo;
    }

void printVetor(no * vetor){
    no * vetoraux = vetor;
    for (int n = 0; n<= 9; n++){
        if(vetoraux[n].next == NULL){
            printf("->[NULL]\n");}
        else{
            do{
                printf("-> [id: %d] ", (vetoraux[n]).next->id);                
                (vetoraux[n]).next = (vetoraux[n]).next -> next;          
            } while ((vetoraux[n]).next != NULL);
            printf("-> [NULL]\n");
        }
    }
}

int main(){
    no vetor[10];
    for (int n = 0; n<= 9; n++){
        (vetor[n]).next = NULL;}
    
    int option;
    do{
        printf("1-insert ints \n2-print hashtable\n5-esc\n");
        scanf("%d", &option);
        switch (option){
        case 1:
            insert(vetor, 10, 'c', 2);
            insert(vetor, 20, 'c', 2);
            insert(vetor, 30, 'c', 3);
            insert(vetor, 40, 'c', 3);
            break;
        case 2:
            printVetor(vetor);
            break;
        case 5:
            printf("End\n");
            break;
        default:
            printf("Invalid\n");
            break;
        };
    }while(option != 5);
    return 0;
}

问题根源

问题确实出在printVetor函数中,你在遍历打印时直接修改了原哈希表的链表指针:

(vetoraux[n]).next = (vetoraux[n]).next -> next;

这行代码会逐步将原链表的头节点往后移动,最终会把哈希表中对应槽位的next指针置为NULL,导致第二次打印时无法找到任何数据。

修复方案

使用临时指针遍历链表,不修改原哈希表的结构:

void printVetor(no * vetor){
    for (int n = 0; n <= 9; n++){
        printf("槽位 %d: ", n);
        // 用临时指针遍历,不改动原链表
        no *current = vetor[n].next;
        if(current == NULL){
            printf("->[NULL]\n");
        }else{
            do{
                printf("-> [id: %d] ", current->id);                
                current = current->next;
            } while (current != NULL);
            printf("-> [NULL]\n");
        }
    }
}

额外优化建议

  1. 简化插入逻辑:插入函数无需分情况判断链表是否为空,直接统一头插即可:
void insert(no * vetor, int idInsert, char nameInsert, int pinsert){
    no *newNo = (no*)malloc(sizeof(no));
    newNo->id = idInsert;
    newNo->name = nameInsert;
    // 统一头插,逻辑更简洁
    newNo->next = vetor[pinsert].next;
    vetor[pinsert].next = newNo;
}
  1. 添加内存释放:避免内存泄漏,可添加哈希表销毁函数:
void freeHashTable(no * vetor){
    for(int n = 0; n <=9; n++){
        no *current = vetor[n].next;
        while(current != NULL){
            no *temp = current;
            current = current->next;
            free(temp);
        }
        vetor[n].next = NULL;
    }
}

在main函数循环结束后调用freeHashTable(vetor);即可。

内容的提问来源于stack exchange,提问作者Caio Gabriel

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 19:35:21