0

I'm getting a segmentation fault when running this. Valgrind reports no errors, but a leak of 1,080 bytes at two blocks, with 5 allocs and only 3 free'd. Below is my load function and below that are my unload and free_node (that I have created to use recursively) functions. I have only filled these functions so far but I guess that shouldn't really matter.

I am using the small dictionary for the time being and a simple hash table (of size 26). Running the program with cat.txt for testing.

Load function:

// Loads dictionary into memory, returning true if successful, else false
bool load(const char *dictionary)
{

    // Open dictionary to read from and check if valid
    FILE *dict = fopen(dictionary, "r");
    if (dict == NULL)
    {
        printf("Cannot read file...\n");
        return false;
    }

    // Create variable buffer
    char buffer;

    // Allocate memory to identified word as node and check if memory is available
    node *n = malloc(sizeof(node));
    if (n == NULL)
    {
        printf("insufficient memory ...\n");
        fclose(dict);
        return false;
    }
    else
    {
        n->next = NULL;
    }

    // Create variable for array counter
    int count = 0;

    // Create variable for hash key
    int hash = 0;

    // Read dictionary character by character
    while (fread(&buffer, sizeof(char), 1, dict))
    {
        // Identify words in dictionary
        if (buffer != '\n')
        {
            // Populate dictword with buffer characters until new line is reached
            n->word[count] = toupper(buffer);
            count++;
        }
        else
        {
            // Hash identified word
            hash = n->word[0] - 65;

            // Link node in hash table
            n->next = table[hash];
            table[hash] = n;

            // Reset array count when new line is reached
            count = 0;
        }
    }

    // Close dictionary
    fclose(dict);
    return true;
}

Unload and free_node functions

// Unloads dictionary from memory, returning true if successful, else false
bool unload(void)
{
    // Iterate through each element of hash table
    for (int i = 0; i < N; i++)
    {
        node *tmp = table[i];
        free_node(tmp);
    }
    return true;
}

void free_node(node *tmp)
{
    if (tmp == NULL)
    {
        return;
    }
    free_node(tmp->next);
    free(tmp);
}

Ran debug50 a few times with breakpoints in all three functions. The program seems to be looping in the free_node function when checking for nodes at table[2] (i.e. at letter c) which is linked to two nodes (cat and catterpillar). It keeps on calling free(tmp->next) ad infinitum causing a stack overflow.

Thank you for your help!

1
  • Could you also add the check function. There may be some problem in it
    – Vsjain
    Commented Jan 20, 2021 at 16:24

1 Answer 1

1

There is a serious logic problem here. The load code only allocates one node, before the start of the while loop. All words are going to be added to that one node. (I leave it to you to study exactly how words are being assigned after the first one.)

The code needs to allocate a new node for each word.

Any remaining issues could simply be a result of this problem. Diagnosing them at this point serves no useful purpose.

If this answers your question, please click on the check mark to accept. Let's keep up on forum maintenance. ;-)

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .