Cs50 Speller未初始化的值是由堆分配错误创建的

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

我有一些代码,应该带一个字典文件,读取每个单词并将其添加到trie数据结构中,在单词的最后一个节点上将bool设置为true。

它运行,但是当我稍后在check()函数中对照字典检查单词时,它总是在说假。

Valgrind抛出此错误;

    ==20700== 
    ==20700== Conditional jump or move depends on uninitialised value(s)
    ==20700==    at 0x40116F: load (dictionary.c:114)
    ==20700==    by 0x400834: main (speller.c:40)
    ==20700==  Uninitialised value was created by a heap allocation
    ==20700==    at 0x4C2FB0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
    ==20700==    by 0x401180: load (dictionary.c:116)
    ==20700==    by 0x400834: main (speller.c:40)
    ==20700== 
    Killed

[我环顾四周,并添加了遍历子代的循环[],并在创建新节点后初始化为NULL,但似乎仍然存在问题。

// Represents a node in a trie
typedef struct node
{
    bool is_word;
    struct node *children[N];
}
node;

// Represents a trie
node *root;

// Loads dictionary into memory, returning true if successful else false
bool load(const char *dictionary)
{
    // Initialize trie
    root = malloc(sizeof(node));
    if (root == NULL)
    {
        return false;
    }
    root->is_word = false;
    for (int i = 0; i < N; i++)
    {
        root->children[i] = NULL;
    }

    // Open dictionary
    FILE *file = fopen(dictionary, "r");
    if (file == NULL)
    {
        unload();
        return false;
    }

    //declare pointer to store adress of current node
    node *ptr = root;

    // Buffer for a word
    char word[LENGTH + 1];

    for (int i = 0; i < LENGTH + 1; i++)
        {
            word[i] = 0;
        }

    int size = 0;

    // Insert words into trie
    while (fscanf(file, "%s", word) != EOF)
    {

        // make pointer to current place in trie structure and intitialise to root
        ptr = root;

        // make variable to store chaacter as int representing position in alphabet
        int alphaindex;

        // iterate over letters in word
        for (int i =0; i < LENGTH; i++)
        {



            // if word i == to ' character check ptr children and make new node if necesary
            if ((int)&word[i] == '\'')
            {
                alphaindex = 26;
                if (ptr-> children[alphaindex] == NULL)
                {
                    node *n = malloc(sizeof(node));

                    if (n == NULL)
                    {
                        return 1;
                    }

                    root->is_word = false;

                    for (int j = 0; j < N; j++)
                    {
                        root->children[j] = NULL;
                    }


                    // set 27th element of children to new node
                    ptr -> children[alphaindex] = n;
                }

                // set ptr to ptr[26]

                ptr = ptr -> children[alphaindex];

            }

            else
            {

                // adjust alphainex
                alphaindex = islower((int) word[i]) ? (int) word[i] - 97 : (int) word[i] - 65;

                //check location for NULL and make new index if necessary
                if (ptr -> children[alphaindex] == NULL)
                {
                    node *n = malloc(sizeof(node));

                    if (n == NULL)
                    {
                        return 1;
                    }

                    root->is_word = false;

                    for (int k = 0; k < N; k++)
                    {
                        root->children[k] = NULL;
                    }

                    // set children[alphaindex] to new node
                    ptr -> children[alphaindex] = n;

                    //set ptr to new alphaindex element of array which its self points to the new node
                    ptr = ptr -> children[alphaindex];
                }

                else
                {

                //set ptr to new alphaindex element of array which its self points to the new node
                ptr = ptr -> children[alphaindex];

                }


            }



            // if the character is 0 word is over, set is_word and return to while loop
            if((char) word[i + 1] == 0)
            {
                ptr -> is_word = true;
                size ++;
                break;
            }



        }



    }

    printf("Size of dictionary = %i\n", size);

    // Close dictionary
    fclose(file);

    // Indicate success
    return true;
}

我非常确定,有此错误的条件是我评估天气或不创建新节点的情况,当我稍后尝试对其进行测试时,这将导致错误。

感谢您的帮助

Alex

c valgrind cs50
1个回答
0
投票

几个即时问题:

如果单词包含撇号,则根目录中的所有指针都在此处设置为NULL:

for (int j = 0; j < N; j++)
                    {
                        root->children[j] = NULL;
                    }

错别字?这将使它们“无法释放”(更不用说,检查永远找不到它们)。

else分支中的相同问题:

for (int k = 0; k < N; k++)
                    {
                        root->children[k] = NULL;
                    }

撇号检查必须是离散的。看起来程序似乎没有“保存”足够的指针,但是在纠正这些大的结构性问题之前,您将无法完成该工作。

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