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

while循环中使用scanf导致哈希表原有值被覆盖的问题排查

问题分析与修复

你的代码出现“新输入值替换所有原有值”的问题,核心原因是哈希表中存储的都是同一个指针,且该指针指向的内存被重复覆盖,同时哈希函数也存在逻辑错误,具体问题和修复如下:

关键错误点

1. 未正确为输入字符串分配内存,scanf使用错误

add函数中char* input;仅声明了指针,未指向任何有效内存空间。你用scanf("%s", (char*)&input);直接将输入内容写入指针变量自身的地址,这会破坏指针的存储,且每次调用add时,input作为局部变量,其内存地址固定。哈希表中存储的都是这个固定地址的指针,后续输入会覆盖该地址的内容,导致所有指向该地址的哈希表项都显示新值。

2. 哈希函数计算错误

hash函数中sizeof(str)获取的是指针的字节长度(如32位系统是4,64位是8),而非输入字符串的实际长度。这会导致只计算字符串前几个字符的ASCII值,哈希结果不准确,出现多个输入映射到同一哈希桶的情况。

3. 未复制输入字符串到哈希表

即使修正了内存分配,直接将局部变量的指针存入哈希表也会导致函数结束后指针失效,必须复制输入的字符串到堆内存中,再将堆内存的指针存入哈希表。

修复后的代码

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

#define T_LEN 10

// 初始化哈希表,将每个元素置为NULL
void init(char* table[]) {
    for (int i = 0; i < T_LEN; i++) {
        table[i] = NULL;
    }
}

// 修正后的哈希函数:使用strlen获取字符串长度
int hash(char* str) {
    int result = 0;
    for (int i = 0; i < strlen(str); i++) {
        result += str[i];
    }
    return result % T_LEN;
}

// 修正后的添加函数:分配内存存储输入字符串
void add(char* table[]) {
    char input[100]; // 用栈数组临时存储输入,避免内存泄漏风险
    printf("> ");
    scanf("%99s", input); // 限制输入长度,防止缓冲区溢出
    
    int index = hash(input);
    // 先释放原有内存(如果存在),避免内存泄漏
    if (table[index] != NULL) {
        free(table[index]);
    }
    // 复制字符串到堆内存,存入哈希表
    table[index] = strdup(input);
    if (table[index] == NULL) {
        printf("内存分配失败\n");
        exit(1);
    }
}

// 打印哈希表的实现(补充原代码缺失部分)
void print_table(char* table[]) {
    for (int i = 0; i < T_LEN; i++) {
        printf("%d\t%s\n", i+1, table[i] != NULL ? table[i] : "-------");
    }
}

int main() {
    char* hash_table[T_LEN];
    init(hash_table);
    while (1) {
        add(hash_table);
        print_table(hash_table);
    }
    // 注意:实际使用中需要在退出前释放哈希表的内存,避免泄漏
    return 0;
}

修复说明

  • 使用栈数组input临时存储输入,再通过strdup将字符串复制到堆内存,确保哈希表中存储的指针指向独立的、持久的内存空间。
  • 哈希函数改用strlen遍历整个字符串,计算准确的哈希值。
  • 初始化哈希表时将元素置为NULL,便于判断桶是否为空,且释放内存时更安全。
  • 添加了输入长度限制,防止缓冲区溢出。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 01:41:04