Skip to main content
deleted 22 characters in body; edited tags; edited title
Source Link
UpAndAdam
  • 1.7k
  • 1
  • 3
  • 20

pset 4 - Speller hash table - unload memory not working

// Loads dictionary into memory, returning true if successful else false
bool load(const char *dictionary)
{
    // Initialize hash table
    for (int i = 0; i < N; i++)
    {
        hashtable[i] = NULL;
    }

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

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

    // Insert words into hash table
    while (fscanf(file, "%s", word) != EOF)
    {
        node *new_node = malloc(sizeof(node));
        if (new_node == NULL) // if malloc did not work
        {
            unload();
            return false;
        }
        else
        {
            strcpy(new_node->word, word);

            int first_letter_number = hash(word);

            // insert new_node at beginning of linked list
            new_node->next = hashtable[first_letter_number];
            hashtable[first_letter_number] = new_node;
            dict_word_count++;
        }
    }

    // Close dictionary
    fclose(file);

    // Indicate success
    return true;
}

unload:

 
// Unloads dictionary from memory, returning true if successful else false
bool unload(void)
{
    int nodes_freed = 0;
    int elements_freed = 0;

    // free the nodes
    for (int i = 0; i < N; i++)
    {
        for (node *ptr = hashtable[i]; ptr != NULL; ptr = ptr->next)
        {
            free(ptr);
            nodes_freed++;
        }
    }

    // free the hash table
    for (int i = 0; i < N; i++)
    {
        if (hashtable[i])
        {
            free(hashtable[i]);
            elements_freed = 0;
        }
    }

    printf("Number of nodes freed: %i\n", nodes_freed);
    printf("Number of hashtable elements freed: %i\n", elements_freed);

    return true;
}

pset 4 - Speller hash table - unload memory not working

// Loads dictionary into memory, returning true if successful else false
bool load(const char *dictionary)
{
    // Initialize hash table
    for (int i = 0; i < N; i++)
    {
        hashtable[i] = NULL;
    }

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

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

    // Insert words into hash table
    while (fscanf(file, "%s", word) != EOF)
    {
        node *new_node = malloc(sizeof(node));
        if (new_node == NULL) // if malloc did not work
        {
            unload();
            return false;
        }
        else
        {
            strcpy(new_node->word, word);

            int first_letter_number = hash(word);

            // insert new_node at beginning of linked list
            new_node->next = hashtable[first_letter_number];
            hashtable[first_letter_number] = new_node;
            dict_word_count++;
        }
    }

    // Close dictionary
    fclose(file);

    // Indicate success
    return true;
}

unload:

// Unloads dictionary from memory, returning true if successful else false
bool unload(void)
{
    int nodes_freed = 0;
    int elements_freed = 0;

    // free the nodes
    for (int i = 0; i < N; i++)
    {
        for (node *ptr = hashtable[i]; ptr != NULL; ptr = ptr->next)
        {
            free(ptr);
            nodes_freed++;
        }
    }

    // free the hash table
    for (int i = 0; i < N; i++)
    {
        if (hashtable[i])
        {
            free(hashtable[i]);
            elements_freed = 0;
        }
    }

    printf("Number of nodes freed: %i\n", nodes_freed);
    printf("Number of hashtable elements freed: %i\n", elements_freed);

    return true;
}

Speller hash table - unload memory not working

// Loads dictionary into memory, returning true if successful else false
bool load(const char *dictionary)
{
    // Initialize hash table
    for (int i = 0; i < N; i++)
    {
        hashtable[i] = NULL;
    }

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

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

    // Insert words into hash table
    while (fscanf(file, "%s", word) != EOF)
    {
        node *new_node = malloc(sizeof(node));
        if (new_node == NULL) // if malloc did not work
        {
            unload();
            return false;
        }
        else
        {
            strcpy(new_node->word, word);

            int first_letter_number = hash(word);

            // insert new_node at beginning of linked list
            new_node->next = hashtable[first_letter_number];
            hashtable[first_letter_number] = new_node;
            dict_word_count++;
        }
    }

    // Close dictionary
    fclose(file);

    // Indicate success
    return true;
}
 
// Unloads dictionary from memory, returning true if successful else false
bool unload(void)
{
    int nodes_freed = 0;
    int elements_freed = 0;

    // free the nodes
    for (int i = 0; i < N; i++)
    {
        for (node *ptr = hashtable[i]; ptr != NULL; ptr = ptr->next)
        {
            free(ptr);
            nodes_freed++;
        }
    }

    // free the hash table
    for (int i = 0; i < N; i++)
    {
        if (hashtable[i])
        {
            free(hashtable[i]);
            elements_freed = 0;
        }
    }

    printf("Number of nodes freed: %i\n", nodes_freed);
    printf("Number of hashtable elements freed: %i\n", elements_freed);

    return true;
}
Source Link

pset 4 - Speller hash table - unload memory not working

Good afternoon

Hitting the last hurdle with unloading memory, can't figure where I'm going wrong

Code to load the hash table:

// Loads dictionary into memory, returning true if successful else false
bool load(const char *dictionary)
{
    // Initialize hash table
    for (int i = 0; i < N; i++)
    {
        hashtable[i] = NULL;
    }

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

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

    // Insert words into hash table
    while (fscanf(file, "%s", word) != EOF)
    {
        node *new_node = malloc(sizeof(node));
        if (new_node == NULL) // if malloc did not work
        {
            unload();
            return false;
        }
        else
        {
            strcpy(new_node->word, word);

            int first_letter_number = hash(word);

            // insert new_node at beginning of linked list
            new_node->next = hashtable[first_letter_number];
            hashtable[first_letter_number] = new_node;
            dict_word_count++;
        }
    }

    // Close dictionary
    fclose(file);

    // Indicate success
    return true;
}

unload:

// Unloads dictionary from memory, returning true if successful else false
bool unload(void)
{
    int nodes_freed = 0;
    int elements_freed = 0;

    // free the nodes
    for (int i = 0; i < N; i++)
    {
        for (node *ptr = hashtable[i]; ptr != NULL; ptr = ptr->next)
        {
            free(ptr);
            nodes_freed++;
        }
    }

    // free the hash table
    for (int i = 0; i < N; i++)
    {
        if (hashtable[i])
        {
            free(hashtable[i]);
            elements_freed = 0;
        }
    }

    printf("Number of nodes freed: %i\n", nodes_freed);
    printf("Number of hashtable elements freed: %i\n", elements_freed);

    return true;
}

My thinking for the unload is first to free all the nodes within the linked lists for each letter a..z

Then free each element in the array hashtable

Number of words in the dictionary is 143,091 and the number of nodes being freed is this exact number per printf above (number of hashtable elements freed is 0 so looks like they're all being cleared when freeing the nodes)

Valgrind log:

==9232== Memcheck, a memory error detector
==9232== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==9232== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==9232== Command: ./speller ./texts/lalaland.txt
==9232== Parent PID: 187
==9232==
==9232== Invalid read of size 8
==9232==    at 0x401244: unload (dictionary.c:130)
==9232==    by 0x400E49: main (speller.c:153)
==9232==  Address 0x534b6a0 is 48 bytes inside a block of size 56 free'd
==9232==    at 0x4C30D3B: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==9232==    by 0x40123F: unload (dictionary.c:132)
==9232==    by 0x400E49: main (speller.c:153)
==9232==  Block was alloc'd at
==9232==    at 0x4C2FB0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==9232==    by 0x40115E: load (dictionary.c:56)
==9232==    by 0x4009A4: main (speller.c:41)
==9232==
==9232== Invalid free() / delete / delete[] / realloc()
==9232==    at 0x4C30D3B: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==9232==    by 0x40129B: unload (dictionary.c:141)
==9232==    by 0x400E49: main (speller.c:153)
==9232==  Address 0x534b670 is 0 bytes inside a block of size 56 free'd
==9232==    at 0x4C30D3B: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==9232==    by 0x40123F: unload (dictionary.c:132)
==9232==    by 0x400E49: main (speller.c:153)
==9232==  Block was alloc'd at
==9232==    at 0x4C2FB0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==9232==    by 0x40115E: load (dictionary.c:56)
==9232==    by 0x4009A4: main (speller.c:41)
==9232==
==9232==
==9232== HEAP SUMMARY:
==9232==     in use at exit: 0 bytes in 0 blocks
==9232==   total heap usage: 143,096 allocs, 143,122 frees, 8,023,416 bytes allocated
==9232==
==9232== All heap blocks were freed -- no leaks are possible
==9232==
==9232== For counts of detected and suppressed errors, rerun with: -v
==9232== ERROR SUMMARY: 143117 errors from 2 contexts (suppressed: 0 from 0)

Any ideas?