免责声明:这是一个家庭作业问题。显而易见,我试图自己解决它。我似乎遇到了一个我无法弄清楚的问题,所以一些帮助将不胜感激。
我需要散列一组单词,然后将其插入到链接列表数组中。因此,如果3个不同的单词具有散列38,则在数组[38]中,我需要有一个包含3个单词的链表。
我正在使用这个结构
struct Word {
char* word;
struct Word* next;
};
在哈希之后,我将它插入到数组中:
struct Word* table[1000]; // array of linked-lists
char word[128];
while(fgets(word, sizeof(word), dict) != NULL) {
hashValue = hashWord(word, strlen(word));
struct Word *newWord = malloc(sizeof(struct Word));
newWord->word = word;
if (table[hashValue] == NULL) {
table[hashValue] = newWord;
} else { // at index hashValue, table already contains at least one element
// insert new word as first element of linked-list
newWord->next = table[hashValue];
table[hashValue] = newWord;
}
}
我知道有大约5个单词的哈希值为38,但是当我打印它们时,我会得到相同的单词5次:
struct Word* foo = table[38];
while (foo->next != NULL) {
printf("%s", foo->word); // prints the same word every time
foo = foo->next;
}
我似乎在某些时候覆盖了我的链表,但我无法弄清楚在哪里。
答案 0 :(得分:5)
while(fgets(word, sizeof(word), dict) != NULL) {
...
newWord->word = word;
问题是你要替换word
的内容,这是每个newWord
中存储的指针。
每次使用此行在堆上分配一个新的Word
结构:
struct Word *newWord = malloc(sizeof(struct Word));
但这只为Word
结构本身分配内存; Word
结构包括char *word
- 即。指向字符的指针(在这种情况下是NUL终止的字符串),但它实际上并不包含字符串本身的任何空格。
现在需要为字符串显式分配内存。试试这个:
newWord->word = strdup(word);
这会将word
的副本放入每个Word
结构中。在fgets()
循环中调用next while
时,不会覆盖此副本。请记住堆栈分配的字符数组:
char word[128];
仅在执行此功能时有效;你必须在堆上分配一些东西(使用malloc()
,或使用它的东西,如strdup()
),如果你希望它超出函数调用的话。
完成后,在释放每个free()
之前,不要忘记char *word
Word*
s。
答案 1 :(得分:1)
你正在覆盖单词数组。您只存储指向数组的指针,但每个新单词都会覆盖该数组。你需要单独的记忆来保存每个单词。