C语言实现哈希表调用strcpy拷贝数据时出现段错误求助
问题原因&修复方案
直接触发段错误的核心原因
main函数中声明的char *writeTo是未初始化的野指针,没有分配任何可写入的内存空间,调用strcpy往该非法地址写入数据时直接触发段错误。
其他隐藏的致命问题
- 柔性数组内存分配错误:
struct Node中的char data[]是柔性数组,malloc(sizeof(struct Node))仅分配了指针成员Next的空间,未包含字符串存储所需的内存,需要改为malloc(sizeof(struct Node) + strlen(data) + 1),额外+1是为了存储字符串末尾的'\0'结束符。 - 字符串比较逻辑错误:遍历哈希冲突链表时用
newNode->data == input比较的是两个字符串的内存地址,而非字符串内容,需要改为strcmp(newNode->data, input) == 0。 - 空指针访问顺序错误:
search函数中先打印hashTable[hashed]->data再判断hashTable[hashed] == NULL,如果对应哈希桶为空会提前触发空指针访问崩溃,需要把空判断逻辑放到访问data成员之前。 - 哈希数组越界风险:原哈希函数返回值没有做取模限制,可能超出0~99的下标范围,访问
hashTable时会越界,需要在哈希函数返回前添加% size的取模逻辑。 - 哈希表定义不合法:全局声明的
struct Node *hashTable[]是不完整数组类型,需要指定长度为struct Node *hashTable[size]。 - 函数返回值不匹配:
search函数声明返回char *但实际没有返回任何值,可将返回值改为void。 - 哈希函数逻辑冗余错误:自定义的
round函数参数类型为int,传入float值会被截断,且未引入<math.h>就使用floor/ceil,哈希计算用浮点数既没必要也容易出现精度问题,建议直接改用整数哈希逻辑。
修正后的完整代码
#include <stdio.h> #include <stdlib.h> #include <string.h> #define size 100 // 哈希函数改用整数计算,避免浮点数精度问题 int hash(char input[]){ unsigned int number = 0; int len = strlen(input); for(int i = 0; i < len; i++){ number += input[i]; } // 取模保证下标在合法范围内 return number % size; } struct Node{ struct Node *Next; char data[]; }; // 明确指定哈希表长度 struct Node *hashTable[size]; struct Node *createNode(char *data){ int len = strlen(data); // 为柔性数组分配足够的存储空间 struct Node *newNode = malloc(sizeof(struct Node) + len + 1); newNode->Next = NULL; strcpy(newNode->data, data); return newNode; } void createHashTable(){ for(int i = 0; i < size; i++){ hashTable[i] = NULL; } } void addToHashTable(char *input){ int hashed = hash(input); if(hashTable[hashed] == NULL){ hashTable[hashed] = createNode(input); } else{ struct Node *newNode = createNode(input); newNode->Next = hashTable[hashed]; hashTable[hashed] = newNode; } } // 返回值改为void,无需返回指针 void search(char input[], char *writeTo){ int hashed = hash(input); // 先判空再访问成员 if(hashTable[hashed] == NULL){ strcpy(writeTo, "not found"); return; } printf("\nhashed: %d", hashed); printf("\ndata: %s", hashTable[hashed]->data); if(hashTable[hashed]->Next == NULL){ printf("\nit is: %s", hashTable[hashed]->data); strcpy(writeTo, hashTable[hashed]->data); return; } else{ struct Node *cur = hashTable[hashed]; while(cur != NULL){ // 用strcmp比较字符串内容 if(strcmp(cur->data, input) == 0){ strcpy(writeTo, cur->data); return; } cur = cur->Next; } // 遍历完未找到也要写入结果 strcpy(writeTo, "not found"); return; } } int main() { createHashTable(); addToHashTable("124"); // 分配足够的栈空间存储返回的字符串 char writeTo[100]; search("124", writeTo); printf("\n查询结果:%s", writeTo); return 0; }
内容的提问来源于stack exchange,提问作者Eric
相关产品推荐
相关产品推荐

