【发布时间】:2015-07-12 04:43:21
【问题描述】:
我是 C 新手,所以在制作哈希表和分配空间时遇到了麻烦。
我正在做一个字谜求解器。现在我还在为这个程序创建哈希表的步骤。我正在尝试通过使用一些随机参数调用该函数一次来测试我的插入函数以查看它是否正常工作。
但是,我不断遇到分段错误,我使用 valgrind 来追踪它崩溃的位置。
你能指出我错过了什么吗?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int hash(char *word)
{
int h = 0;
int i, j;
char *A;
char *a;
// an array of 26 slots for 26 uppercase letters in the alphabet
A = (char *)malloc(26 * sizeof(char));
// an array of 26 slots for 26 lowercase letters in the alphabet
a = (char *)malloc(26 * sizeof(char));
for (i = 0; i < 26; i++) {
A[i] = (char)(i + 65); // fill the array from A to Z
a[i] = (char)(i + 97); // fill the array from a to z
}
for (i = 0; i < strlen(word); i++) {
for (j = 0; j < 26; j++) {
// upper and lower case have the same hash value
if (word[i] == A[j] || word[i] == a[j]) {
h += j; // get the hash value of the word
break;
}
}
}
return h;
}
typedef struct Entry {
char *word;
int len;
struct Entry *next;
} Entry;
#define TABLE_SIZE 20 // test number
Entry *table[TABLE_SIZE] = { NULL };
void init() {
// create memory spaces for each element
struct Entry *en = (struct Entry *)malloc(sizeof(struct Entry));
int i;
// initialize
for (i = 0; i < TABLE_SIZE; i++) {
en->word = "";
en->len = 0;
en->next = table[i];
table[i] = en;
}
}
void insertElement(char *word, int len) {
int h = hash(word);
int i = 0;
// check if value has already existed
while(i < TABLE_SIZE && (strcmp(table[h]->word, "") != 0)) {
// !!!! NEXT LINE IS WHERE IT CRASHES !!!
if (strcmp(table[h]->word, word) == 0) { // found
table[h]->len = len;
return; // exit function and skip the rest
}
i++; // increment loop index
}
// found empty element
if (strcmp(table[h]->word, "") == 0) {
struct Entry *en;
en->word = word;
en->len = len;
en->next = table[h];
table[h] = en;
}
}
int main() {
init(); // initialize hash table
// test call
insertElement("kkj\0", 2);
int i;
for ( i=0; i < 10; i++)
{
printf("%d: ", i);
struct Entry *enTemp = table[i];
while (enTemp->next != NULL)
{
printf("Word: %s, Len:%d)", enTemp->word, enTemp->len);
enTemp = enTemp->next;
}
printf("\n");
}
return 0;
}
【问题讨论】:
-
怀疑你想要一个副本:
en->word = strdup(word); -
注意:这只会使 1
enstruct Entry *en = (struct Entry *)malloc(sizeof(struct Entry)); -
关于系统函数" malloc() 1) 不要强制转换返回值 2) 始终检查 (!=NULL) 返回值以确保操作成功
-
关于这一行:'insertElement("kkj\0", 2);'文字“kkj\0”的格式不正确。当定义一个 char 数组时,比如这个字面量,编译器会自动附加一个 '\0' 所以这个字面量在内存中会是:'k','k','j','\0','\ 0' 这不是我们所需要的。