Pset 5 CS50 中转储的分段核心

问题描述 投票:0回答:1

我目前正在为 CS50 开发 PSET5 拼写器。我正在尝试实现哈希表并尝试一起加载字典。问题是它一直显示分段错误,我似乎找不到问题所在。我的代码有错误还是无法正常工作?

// Implements a dictionary's functionality

#include <ctype.h>
#include <stdbool.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include "dictionary.h"

// Represents a node in a hash table
typedef struct node
{
    bool is_word;
    struct node *children[26];
}
node;

// TODO: Choose number of buckets in hash table
const unsigned int N = 71;

// Hash table
node *table[N];



//Counts words
int word_count = 0;

// Returns true if word is in dictionary, else false
bool check(const char *word)
{
    // TODO
    return false;
}

// Hashes word to a number
unsigned int hash(const char *word)
{
    // TODO: Improve this hash function

    return tolower(word[0]) - 'a';
}

// Loads dictionary into memory, returning true if successful, else false
bool load(const char *dictionary)
{
    // TODO
    for (int z = 0; z<71; z++) {
        table[z] = malloc(sizeof(node));
        for (int i = 0; i<26; i++) {
            table[z]->children[i] = NULL;
        }
    }
    FILE *file = fopen(dictionary, "r");
    if (file == NULL)
    {
        printf("Could not open %s.\n", dictionary);
        unload();
        return 1;
    }
    int index = 0;
    char word[LENGTH + 1];
    char c;

    while (fread(&c, sizeof(char), 1, file)) {
        if (isalpha(c) || (c == '\'' && index > 0)) {
            word[index] = c;
            index++;
        }

        else if (index>0) {
            word[index] = '\0';
            word_count +=1;
            int hashword = hash(word);
            node *cursor = table[hashword];
            for (int j = 0; j<index; j++) {
                int letterindex = tolower(word[j]) - 'a';
                if (cursor->children[letterindex] == NULL) {
                    node *new = malloc(sizeof(node));
                    if (new == NULL) {
                        printf("ERROR NULL!");
                        return 0;
                    }
                    new->is_word = false;
                    for (int k = 0; k<26; k++) {
                        new->children[k] = NULL;
                    }
                    cursor->children[letterindex] = new;

                }
                cursor = cursor->children[letterindex];

            }
            cursor->is_word = true;

            index = 0;
        }
    }
    return true;
}

// Returns number of words in dictionary if loaded, else 0 if not yet loaded
unsigned int size(void)
{
    // TODO
    return word_count;
}

void unloader(node* current)
{

    for (int i = 0; i < 26; i++)
    {
        if (current->children[i] != NULL)
        {
            unloader(current->children[i]);
        }
    }
    free(current);
}

// Unloads dictionary from memory, returning true if successful, else false
bool unload(void)
{
    // TODO
    for (int i = 0; i<N; i++) {
        if (table[i] != NULL) {
            unloader(table[i]);
        }
    }
    return true;
}

c pointers data-structures cs50
1个回答
0
投票

考虑:

        if (isalpha(c) || (c == '\'' && index > 0)) {
            word[index] = c;
            index++;
        }

代码将“字母状态”授予单个撇号(0x27)(例如:“

don't
”)
字母表中只有 26 个字母,这就是每个节点上
children
的数量。

后来:

            int letterindex = tolower(word[j]) - 'a';

0x27 (

'\''
) - 0x61 (
'a'
) ==>(负索引)

因此任何使用

cursor->children[letterindex]
都会调用 UB...

可能还有更多,但这可能是一个主要错误。

© www.soinside.com 2019 - 2024. All rights reserved.