这个简单C语言哈希表实现的insert函数为何无法正常工作?
哈希表代码问题排查与修复
错误点梳理
- 野指针访问是程序直接崩溃、后续代码不执行的核心原因:
createNewElement函数中声明的Element* item未调用malloc申请结构体内存,直接操作成员变量属于非法内存访问,会触发段错误。同时结构体中的names字符指针也未分配内存,直接调用strcpy会再次触发非法访问。 - 打印函数语法错误:
print中&hashTable[i]->names写法错误,该表达式获取的是指针变量的地址,不是字符串首地址,打印会输出乱码或崩溃。 - 无哈希表满校验逻辑:当数组11个位置全部被占用时,
insert中的while循环会进入无限死循环。 - 缺少字符串长度校验:输入字符串长度超过
MAX_STRING_SIZE时会发生缓冲区溢出。
修复后的完整可运行代码
#include<stdio.h> #include<stdlib.h> #include <string.h> #define MAX_STRING_SIZE 20 #define ARRAY_SIZE 11 typedef struct Element Element; struct Element{ char* names; int freq; }; Element* hashTable[ARRAY_SIZE]; int elem_count = 0; // 记录哈希表中已有元素数量,用于判断是否已满 int hash_function(char* s){ int hash = 0; while(*s){ hash = (hash + *s)%ARRAY_SIZE; s++; } return hash; } Element* createNewElement(char* name){ // 先为结构体分配内存 Element* item = (Element*)malloc(sizeof(Element)); if(item == NULL) { printf("结构体内存分配失败\n"); return NULL; } // 校验字符串长度,避免溢出 int name_len = strlen(name); if(name_len >= MAX_STRING_SIZE) { printf("字符串长度超过限制\n"); free(item); return NULL; } // 为字符串分配内存,长度+1存储结束符'\0' item->names = (char*)malloc(sizeof(char) * (name_len + 1)); if(item->names == NULL) { printf("字符串内存分配失败\n"); free(item); return NULL; } strcpy(item->names, name); item->freq = 1; return item; } void insert(char* name){ if(elem_count >= ARRAY_SIZE) { printf("哈希表已满,无法插入新元素\n"); return; } Element* b = createNewElement(name); if(b == NULL) return; int index = hash_function(name); while(hashTable[index] != NULL) { index = (index + 1) % ARRAY_SIZE; } hashTable[index] = b; elem_count++; } void print() { int i; for(i = 0; i < ARRAY_SIZE; i++) { if(hashTable[i] != NULL) printf("%d: %s\n", i, hashTable[i]->names); else printf("%d: -----\n", i); } } // 内存释放函数,避免内存泄漏 void freeHashTable() { for(int i = 0; i < ARRAY_SIZE; i++) { if(hashTable[i] != NULL) { free(hashTable[i]->names); free(hashTable[i]); } } } int main() { insert("jacob"); print(); freeHashTable(); return 0; }
内容的提问来源于stack exchange,提问作者Kartik Mann
相关产品推荐
相关产品推荐

