在过去的 48 小时左右,我一直在努力尝试在 C 中实现这个哈希表函数。我的代码相当长(我意识到它不是最有效的,其中一些更多的是我在玩 C 来获得感觉它是如何工作的等)。
我遇到的问题是底部的主程序的最后一行(打印 MyEntry->Name)。我收到总线错误,不确定原因。我不相信我应该在主驱动程序中为这个指针分配内存,但我可能是错的。
很抱歉这段代码的长度。BTW SymEntry 是 'struct SymEntry{char *Name, void *Attributes, struct SymEntry *Next}
#include <strings.h>
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <stdbool.h>
#include "SymTab.h"
struct SymTab * CreateSymTab(int Size)
{
struct SymTab *symtable;
if(!(symtable=malloc(sizeof(struct SymTab)))) return NULL;
if(!(symtable->Contents=calloc(Size, sizeof(struct SymEntry*)))) {
free(symtable);
return NULL;
}
symtable->Size=Size;
return symtable;
}
/* hash form hash value for string s, taken from 'The C Programming Language'*/
unsigned hash(struct SymTab *ATable, const char *s)
{
unsigned hashval, size;
size = ATable->Size;;
for (hashval = 0; *s != '\0'; s++)
hashval = *s + 31 * hashval;
return hashval % size;
}
bool EnterName(struct SymTab *ATable,
const char *Name,
struct SymEntry **AnEntry)
{
struct SymEntry *ptr;
unsigned hashvalue;
char *string;
struct SymEntry *previous;
string = malloc(strlen(Name)+1);
AnEntry=(struct SymEntry**)malloc(sizeof(struct SymEntry*));
strcpy(string, Name);
printf("string is: is %s\n",string);
hashvalue = hash(ATable, string);
printf("hv is %d\n",hashvalue);
ptr = ATable->Contents[hashvalue];
previous = NULL;
while(ptr)
{
printf("WHILE LOOP\n");
if(!(strcmp(ptr->Name,string)))
{
printf("if(!strcmp(ptr->Name,string))\n");
*AnEntry = ptr;
return true;
}
previous = ptr;
ptr=ptr->Next;
}
if(previous)
{
printf("IF (PREVIOUS)\n");
if(!(ptr=malloc(sizeof(struct SymEntry)))) return false;
if(!(ptr->Name=string))
{
printf("if(!(ptr->Name=string))\n");
free(ptr);
return false;
}
ptr->Name = string;
previous->Next = ptr;
printf("Previous->Next: %s\n", previous->Next->Name);
*AnEntry = ptr;
return false;
}
else
{
printf("ELSE (PREVIOUS)\n");
if(!(ptr=malloc(sizeof(struct SymEntry)))) return false;
if(!(ptr->Name=string))
{
printf("if(!(ptr->Name=string))\n");
free(ptr);
return false;
}
ptr->Name = string;
ATable->Contents[hashvalue] = ptr;
printf("here\n");
*AnEntry = ptr;
printf("there\n");
return false;
}
}
struct SymEntry * FindName(struct SymTab *ATable, const char *Name)
{
struct SymEntry *Entry;
unsigned hashvalue;
hashvalue = hash(ATable, Name);
Entry = ATable->Contents[hashvalue];
while(Entry)
{
if(strcmp(Name,Entry->Name)==0)
{
return Entry;
}
}
return NULL;
}
main(int argc, char **argv)
{
struct SymTab *mysymtab;
struct SymEntry *myEntry;
mysymtab = CreateSymTab(1);
const char *string1 = "HELLO";
printf("%d\n",6);
EnterName(mysymtab, string1, &myEntry);
printf("first: %s\n", mysymtab->Contents[0]->Name);
EnterName(mysymtab, string1, NULL);
EnterName(mysymtab, "WORLD", NULL);
printf("second: %s\n", mysymtab->Contents[0]->Name);
printf("second->Next: %s\n", mysymtab->Contents[0]->Next->Name);
EnterName(mysymtab, "!@#$%", &myEntry);
printf("third: %s\n", mysymtab->Contents[0]->Name);
printf("third->Next: %s\n", mysymtab->Contents[0]->Next->Name);
printf("third->Next->Next: %s\n", mysymtab->Contents[0]->Next->Next->Name);
printf("myEntry->Name: %s\n", myEntry->Name);
}