我是C编程新手。我试着在CS50中做pset5,同时试着理解内存、链表和哈希表的概念。我编写了代码并对其进行了编译,但似乎有问题,因为每次我试图执行代码时,它都会返回一些垃圾值。有人能帮我吗?非常感谢。

#include<stdio.h>
#include<stdlib.h>
#include<ctype.h>
#include<string.h>

#include "dictionary.h"

#define DICTIONARY "dictionaries/small"

typedef struct node
{
char WORD[LENGTH + 1];
struct node *next;
}
node;

int hash(char *word);

int main(void)
{
node **HASHTABLE = malloc(sizeof(node) * 26);

//open the dictionary
FILE *dic = fopen(DICTIONARY, "r");
if (dic == NULL)
{
    fprintf(stderr, "Could not open the library\n");
    return 1;
}

int index = 0;
char word[LENGTH + 1];

for (int c = fgetc(dic); c != EOF; c = fgetc(dic))
{
    word[index] = c;
    index++;

    if (c == '\n')
    {
        int table = hash(word);
        printf("%d\n", table);
        //create a newnode
        node *newnode = malloc(sizeof(node));
        strcpy(newnode->WORD, word);
        newnode->next = NULL;

        printf("Node: %s\n", newnode->WORD);
        index = 0;

        //add new node to hash table
        if (HASHTABLE[table] == NULL)
        {
            HASHTABLE[table] = newnode;
        }
        else
        {
            HASHTABLE[table]->next = newnode;
        }
    }
}
for(int i = 0; i < 26; i++)
{
    node *p = HASHTABLE[i];
    while (p != NULL)
    {
        printf("%s", p->WORD);
        p = p->next;
    }
}

//free memory
for(int i = 0; i < 26; i++)
{
    node *p = HASHTABLE[i];
    while (p != NULL)
    {
        node *temp = p->next;
        free(p);
        p = temp;
    }
}
free(HASHTABLE);
}


int hash(char *word)
{
int i = 0;
if (islower(word[0]))
    return i = word[0] - 'a';
if (isupper(word[0]))
    return i = word[0] - 'A';
return 0;
}

最佳答案

您的代码有严重的问题,会导致未定义的行为。
其中两个是这一行的结果:

node **HASHTABLE = malloc(sizeof(node) * 26);

它分配26个node结构,但HASHTABLE变量需要指向node *指针数组的指针地址(这是**声明中的node **HASHTABLE)。
所以,你应该换成这样的东西:
node **HASHTABLE = malloc( 26 * sizeof( *HASHTABLE ) );

注意,我使用了分配给-HASHTABLE的变量的解引用值。在这种情况下,这意味着anode(比声明中少1*)。因此,如果HASHTABLE的类型发生更改,则不需要对malloc()语句进行任何其他更改。
这个问题,虽然在技术上没有定义行为,但很可能不会导致任何问题。
但是,仍然有一个问题
node **HASHTABLE = malloc( 26 * sizeof( *HASHTABLE ) );

这会导致问题-和严重的问题。
26个指针的数组没有初始化-你不知道它们里面有什么。它们可以指向任何地方。所以这根本不管用,如果:
    if (HASHTABLE[table] == NULL)

意思是指未知的地方:
    HASHTABLE[table]->next = newnode;

这会引起各种各样的问题。
最简单的方法?使用calloc()而不是malloc()将所有值初始化为零:
node **HASHTABLE = calloc( 26, sizeof( *HASHTABLE ) );

在修复之前,整个程序的任何结果充其量都是有问题的。

关于c - CS50-LOAD-尝试执行加载时从无处获取随机字符,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/53327543/

10-12 00:41