0

After fixing and running pset5 most recently yesterday, it made it through check50 with no errors -- all smiley faces. I ran valgrind and found a number of leaks which were repaired by removing an unneccesary calloc. One error still remained:

Helping with...                                                                                                                                                       

==3869== Invalid write of size 1
==3869==    at 0x40138F: load (dictionary.c:126)
==3869==    by 0x40097D: main (speller.c:40)

Looks like you're trying to modify 1 byte of memory that isn't yours? Did you try to store something beyond the bounds of an array? Take a closer look at line 126 of 
dictionary.c.

The line was

current->is_word = true;  

and was placed outside the for loop that loaded each letter of a word from dictionary.

I came back today, moved the statement inside the for loop (which wasn't correct I realized almost as soon as I ran it, because it would make every letter a word), but today I can't run the code at all without immediately getting a segmentation fault. I can't even run the code as it was yesterday when it passed check50. Below is my code as it was for the load function which worked perfectly and in conjunction with my other functions passed all the check50 checks, but did as mentioned not pass valgrind based on above error.

bool load(const char *dictionary)
{
    root = calloc(1, sizeof(node));

    /* added today 7/5/17 -- worked without it yesterday
    root->is_word = false;
    for (int i = 0; i < 27; i++)
    {
        root->children[i] = NULL;
    }
    */

    // to hold the current word
    char word[LENGTH +1];
    FILE *loadin = fopen(dictionary, "r");
    size_count = 0;

   while (fscanf(loadin, "%s", word) != EOF)
   {
        int index = 0;
        // defines constant to use in calculating index
        const int ltr = 'a';   
        // creates root node
        current = root;


        // checks each character in word one by one
        for (int i =0; i < strlen(word); i++)
        {
            // ' is at index 26
            if (word[i] == '\'')
            {
                index = 26;
            }
            // determines index number of letters in words based on lower case ascii mod with base
            else
            {
                index = word[i] % ltr;
            }


            // word and pointer at that "letter" points to nothing
            //    then, create node
            if (current->children[index] == NULL)
            {
                // move current to next node
                current = current->children[index];
            }

            else
            {
                current = current->children[index];
            }


        }
        /* line 126 */current->is_word = true;

        // increase word count
        size_count++;

    }


    return true;
}

Again, today, even though yesterday it compiled, found misspelled words correctly and passed check50, I immediately got a segmentation fault when trying to run it.

EDIT: Please note in for loop, I had a calloc. when I removed that, it made both my if and else statement identical which I haven't fixed yet, but it still ran yesterday in spite of that foolishness.

        if (current->children[index] == NULL)
        {
            current->children[index] = calloc(1,sizeof(node));
            // move current to next node
            current = current->children[index];
        }


        // if pointer already points to something, assign that pointer to current
        else
        {
            current = current->children[index];
        }

EDIT: first run of valgrind with the above code:

Helping with...                                                                                                                                                       

==6357== 82,221,216 (5,824 direct, 82,215,392 indirect) bytes in 26 blocks are definitely lost in loss record 5 of 5
==6357==    at 0x4C2CC70: calloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==6357==    by 0x40131D: load (dictionary.c:115)
==6357==    by 0x40097D: main (speller.c:40)

Looks like your program leaked 82,221,216 bytes of memory. Did you forget to free memory that you allocated via malloc? Take a closer look at line 
115 of dictionary.c.
4
  • This current->children[index] = calloc(1,sizeof(node)); is not an "unnecessary calloc". It is necessary and its absence is likely causing the seg fault. Jul 5 '17 at 20:10
  • I went back to my original. I've edited to include the original valgrind errors in my post as per help50.
    – KitSeason
    Jul 5 '17 at 20:49
  • Does it run now? The "first run of valgrind" errors look like unload didn't "work" (and since the program had passed check50, unload is the likely culprit). Jul 5 '17 at 21:43
  • It does run. Back to the drawing board with unload. I'll ask another question if I can't find answer on unload. Thanks.
    – KitSeason
    Jul 5 '17 at 21:54

You must log in to answer this question.

Browse other questions tagged .