C语言哈希表添加单词报错:array subscript is not an integer 求助
解决CS50 PSET5前置练习中的哈希表错误问题
错误原因分析
你遇到的array subscript is not an integer错误,根源在这行代码:
table[hash] = n;
这里的hash是函数名,本质是一个函数指针,不是整数类型。而数组的下标必须是整数,所以编译器报错。你需要调用hash函数并传入当前读取的单词,才能得到对应桶的整数编号。
核心修正
把错误行改为:
int hash_idx = hash(buffer); table[hash_idx] = n;
通过hash(buffer)调用函数,传入当前读取到的单词buffer,得到0-25之间的整数下标,再用这个下标访问哈希表的对应桶。
额外改进建议
除了核心错误,还有几个需要优化的点,避免潜在问题:
- 修正缓冲区大小:原代码中
buffer的大小是LENGTH,但字符串需要末尾的\0结束符,应该改为char buffer[LENGTH + 1];,否则读取长度为9的单词会导致缓冲区溢出,触发未定义行为。 - 正确插入链表节点:原代码直接覆盖桶的指针,会导致之前插入的节点丢失并引发内存泄漏。应该用头插法将新节点加到链表头部:
n->next = table[hash_idx]; table[hash_idx] = n; - 添加内存清理逻辑:程序结束前遍历哈希表的所有桶,释放每个节点的内存,避免内存泄漏。
- 完善错误处理:补充文件打开失败的提示,以及内存分配失败时的资源清理逻辑。
修正后的完整代码
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <ctype.h> int hash(const char *buffer); const unsigned int LENGTH = 9; typedef struct node { char word[LENGTH + 1]; struct node* next; } node; node *table[26] = {NULL}; int hash(const char *buffer) { return toupper(buffer[0]) - 'A'; } // 清理哈希表所有节点的内存 void free_table(void) { for (int i = 0; i < 26; i++) { node *current = table[i]; while (current != NULL) { node *temp = current; current = current->next; free(temp); } table[i] = NULL; } } int main(void) { FILE *file = fopen("words", "r"); if (file == NULL) { printf("无法打开文件\n"); return 1; } char buffer[LENGTH + 1]; while (fscanf(file, "%s", buffer) != EOF) { node *n = malloc(sizeof(node)); if (n == NULL) { printf("内存分配失败\n"); free_table(); fclose(file); return 1; } strcpy(n->word, buffer); int hash_idx = hash(buffer); // 头插法插入新节点 n->next = table[hash_idx]; table[hash_idx] = n; } fclose(file); free_table(); return 0; }
内容的提问来源于stack exchange,提问作者87lst
相关产品推荐
相关产品推荐

