我决定用C语言制作一个程序,该程序将接受用户输入并使用哈希表进行处理。。。当我放入一些东西时,它在第32行出现分段错误。如下所示:
if (!hashTable[hashIndex].head) {
其余代码:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
struct hash *hashTable = NULL;
int eleCount = 0;
struct node {
int key;
char name[1024];
struct node *next;
};
struct hash {
struct node *head;
int count;
};
struct node * createNode(int key, char *name) {
struct node *newnode;
newnode = (struct node *)malloc(sizeof(struct node));
newnode->key = key;
strcpy(newnode->name, name);
newnode->next = NULL;
return newnode;
}
void insertToHash(int key, char *name) {
int hashIndex = key % eleCount;
struct node *newnode = createNode(key, name);
if (!hashTable[hashIndex].head) {
hashTable[hashIndex].head = newnode;
hashTable[hashIndex].count = 1;
return;
}
newnode->next = (hashTable[hashIndex].head);
hashTable[hashIndex].head = newnode;
hashTable[hashIndex].count++;
return;
}
void deleteFromHash(int key) {
int hashIndex = key % eleCount, flag = 0;
struct node *temp, *myNode;
myNode = hashTable[hashIndex].head;
if (!myNode) {
printf("Word not in hash Table!!n");
return;
}
temp = myNode;
while (myNode != NULL) {
if (myNode->key == key) {
flag = 1;
if (myNode == hashTable[hashIndex].head)
hashTable[hashIndex].head = myNode->next;
else
temp->next = myNode->next;
hashTable[hashIndex].count--;
free(myNode);
break;
}
temp = myNode;
myNode = myNode->next;
}
if (flag)
printf("Word deleted from Hash Table by the power of Grey Skulln");
else
printf("Word is not present in hash Table!n");
return;
}
void searchInHash(int key) {
int hashIndex = key % eleCount, flag = 0;
struct node *myNode;
myNode = hashTable[hashIndex].head;
if (!myNode) {
printf("Searched word not in hash tablen");
return;
}
while (myNode != NULL) {
if (myNode->key == key) {
printf("Key : %dn", myNode->key);
printf("Name : %sn", myNode->name);
flag = 1;
break;
}
myNode = myNode->next;
}
if (!flag)
printf("Searched word not in hash tablen");
return;
}
void display() {
struct node *myNode;
int i;
for (i = 0; i < eleCount; i++) {
if (hashTable[i].count == 0)
continue;
myNode = hashTable[i].head;
if (!myNode)
continue;
printf("Key Wordn");
printf("----------------n");
while (myNode != NULL) {
printf("%-12d", myNode->key);
printf("%-15s", myNode->name);
myNode = myNode->next;
}
}
return;
}
int main() {
int elecount, ch, key, i;
char name[1024],cas[5];
eleCount = 23;
hashTable = (struct hash *)calloc(elecount, sizeof (struct hash));
while (1) {
printf("nword: Insert wordn#d: word Delete wordn");
printf("#s word: Search for wordn#p: Display hash tablen#Q: Exitn");
printf("Enter your choice:");
fgets(name, 1023, stdin);
if(sscanf(name,"#d",&cas)==1)
{//delete
i=2;
while("name[i]"!="n")
{key=key+i;
i++;}
deleteFromHash(key);
}
else if(sscanf(name,"#s",&cas)==1)
{//search
i=2;
while("name[i]"!="n")
{key=key+i;
i++;}
searchInHash(key);
}
else if(sscanf(name,"#p",&cas)==1)
{//print
display();
}
else if(sscanf(name,"#Q",&cas)==1)
{//Quit
exit(0);
}
else
{//insert
while("name[i]"!="n")
{key=key+i;
i++;}
name[strlen(name) - 1] = ' ';
insertToHash(key, name);
}
}
return 0;
}
以下是我认为发布的代码存在的问题:
1) calloc()的第一个参数未初始化
2) 不检查calloc返回的值以确保操作成功
3) calloc的返回值已强制转换,不应为
4) "ch"变量是未使用的
5) 此行:while("name[i]"!="\n")应为:while
6) 没有检查fgets()的返回值以确保操作成功
7) sscan()语句的格式字符串使用了"#",而它们应该使用"%"
8) 变量eleCount未使用
9) 结构定义"node"one_answers"hash"需要在使用这些定义之前
10) malloc返回的值不应强制转换
11) 不检查malloc返回的值以确保操作成功
12) 像这样的行:'else-if(sscanf(name,"#Q",&cas)==1)'是不正确的。它们应该类似于:
else if(sscanf(name,"#Q",&cas)!=1)
{ // then sscanf failed
perror( "sscanf failed" );
exit( EXIT_FAILURE );
}
// implied else, sscanf successful
....
13) 给定输入描述和调用sscan()之后的代码,只需要为char输入"%c"调用sscan然后是该字符上的switch语句。switch语句的情况是检查各种命令对于那些需要"name"操作的命令,则需要if(1!=sscanf(name,"%s",&cas))//句柄错误//隐含的其他//将命令应用于输入名称
14) 数组"cas[]"只有5个char元素因此,如果一个参数大于4个字符,那么就会出现缓冲区溢出,导致未定义的行为,并可能/将导致seg故障事件。
15) 我想这句话是:"key=key+I;"没有按照OP的期望行事。
16) 我想这行是:'insertToHash(key,name);'没有按照作战部的要求
我想我理解OP试图实现的目标,但发布的代码甚至还没有接近编译。
建议OP在编译器中启用所有警告,修复警告和错误,然后进行一些合理的调试活动,如果他们仍然有问题,则重新提出问题。
正如其他人已经说过的,主函数中的calloc使用未初始化的变量elecount而不是elecount。我建议全局变量和局部变量不要使用相同的名称,唯一的区别是大写。你明白为什么了。
在检查.head组件之前,还应该检查变量本身。
因此,首先检查hashTable,然后再进行其他检查。否则,您可能会在NULL处检查组件是否存在。