C语言读取文本文件姓名存入哈希表触发段错误如何解决
问题根因
- 结构体定义错误:你声明的
char* name[20]是长度为20的char指针数组,并未分配可写入的字符串内存空间,*temp->name是未初始化的野指针,直接向该地址写入数据触发段错误。 - 哈希表未初始化:声明的
struct node* hashtable[CAPACITY]所有元素都是野指针,后续插入元素时也会触发非法访问。 - 缺少安全校验:malloc分配内存后未校验是否分配成功,fgets读取的内容未处理末尾换行符,字符串复制未做长度保护。
修复步骤
- 修改结构体定义,将指针数组改为可直接存储字符串的字符数组:
typedef struct node { char name[20]; // 替换原来的char* name[20] struct node* link; } node;
- 初始化哈希表所有槽位为NULL,避免野指针访问
- 替换不安全的sprintf为字符串复制函数,做好长度保护,确保字符串以'\0'结尾
- 处理fgets读取到的换行符,校验malloc返回值
修复后完整代码
#include <stdio.h> #include <stdlib.h> #include <cs50.h> #include <stdint.h> #include <string.h> //node declaration: typedef struct node { char name[20]; struct node* link; } node; unsigned int hash(char* buffer ,unsigned int CAPACITY) ; int main(int argc , string argv[]) { //declarations: FILE* fp = fopen("us-names.txt" , "a+") ; if(fp == NULL) { printf("CANNOT OPEN THE FILE !\n") ; return 1 ; } char buffer[20] ; unsigned int key = 0; unsigned int CAPACITY = 100 ; struct node* temp = NULL ; struct node* hashtable[CAPACITY] ; // 初始化哈希表 for(int i=0; i<CAPACITY; i++){ hashtable[i] = NULL; } //Import name from the FILE & store into buffer: if(fgets(buffer , 20 , fp) != NULL){ // 去掉fgets读取的末尾换行符 int len = strlen(buffer); if(len >0 && buffer[len-1] == '\n'){ buffer[len-1] = '\0'; } //pass the name into the hash_function and get the key: key = hash(buffer , CAPACITY) ; //put the name in a node then in it's right place in the hashtable using the key: temp = malloc(sizeof(struct node)) ; if(temp == NULL){ printf("内存分配失败\n"); fclose(fp); return 1; } // 安全复制字符串 strncpy(temp->name, buffer, sizeof(temp->name)-1); temp->name[sizeof(temp->name)-1] = '\0'; temp->link = NULL; // 头插法插入哈希表槽位 if(hashtable[key] != NULL){ temp->link = hashtable[key]; } hashtable[key] = temp ; } //close the FILE & return 0: fclose(fp) ; return 0; } unsigned int hash(char* buffer , unsigned int CAPACITY) { unsigned int sum = 0 ; for(int i = 0; buffer[i] != '\0' ;i++) { sum += buffer[i] ; } return sum % CAPACITY ; }
内容的提问来源于stack exchange,提问作者Moe Hasan
相关产品推荐
相关产品推荐

