0

Check50 gives me the munmap_chunk: invalid pointer - it seems I am not copying something right with strcpy. Valgrind gives me: LEAK SUMMARY: still reachable: 608 bytes in 2 blocks

==2864== 56 bytes in 1 blocks are still reachable in loss record 1 of 2
==2864==    at 0x4C2FB0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==2864==    by 0x401208: load (dictionary.c:82)
==2864==    by 0x400924: main (speller.c:40)
==2864== 
==2864== 552 bytes in 1 blocks are still reachable in loss record 2 of 2
==2864==    at 0x4C2FB0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==2864==    by 0x5258E49: __fopen_internal (iofopen.c:65)
==2864==    by 0x5258E49: fopen@@GLIBC_2.2.5 (iofopen.c:89)
==2864==    by 0x4011B1: load (dictionary.c:70)
==2864==    by 0x400924: main (speller.c:40)

There is one segmentation fault also. The code I wrote (as a beginner in pointers):

// Implements a dictionary's functionality
#include <ctype.h>
#include <stdbool.h>
#include <strings.h>
#include "dictionary.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

// Represents a node in a hash table
typedef struct node
{
    char word[LENGTH + 1];
    struct node *next;
}
node;

// Number of buckets in hash table
const unsigned int N = 676;    // number will be 26^2

// Hash table
node *table[N];    

// Returns true if word is in dictionary else false
bool check(const char *word)
{

    int x = hash(word);   // going to the index in the table

    // 2 traverse list
    node* cursor = NULL;
    cursor->next = table[x];
    while (cursor != NULL)  // cursor is null at the end of the list
    {
        if (strcasecmp(word, cursor->word) == 0)     // daca exista in lista
        {
            return true;
        }
        cursor = cursor->next;     
    }
    return false;
}
int hvalue;
// Hashes word to a number
unsigned int hash(const char *word)
{

    if  (isupper(word[0]) > 0)       // daca incepe cu litera mare
    {            // mare                 //  mica
        hvalue = (word[0] - 65) * 26 + (word[1] - 96);
        return hvalue;
    }
    else if (isupper(word[1]) > 0)    // highly improbable :OK, KO
    {               // mare               //  mare
        hvalue = (word[0] - 65) * 26 + (word[1] - 65);
        return hvalue;
    }
    else if (word[1] == '\000')    // hash 1 letter words
    {
        hvalue = word[0] - 96;
        return hvalue;
    }
    else
    {
        hvalue = (word[0] - 96) * 26 + (word[1] - 96);    
        return hvalue;
    }
}

int countWords; // for size function

// Loads dictionary into memory, returning true if successful else false
bool load(const char *dictionary)
{
    FILE *file = fopen(dictionary, "r");   // here is line 70 with 1 error
    if (file == NULL)
    {
        fclose(file);
        return false;
    }
    int index;
    char word[46];
    while (fscanf(file, "%s", word) != EOF)      // read in a string
    {
        // create a new node to put the dictionary word
        node *newOne = malloc(sizeof(node));   // here is line 82 with 2nd error
        if (newOne == NULL)
        {
            fclose(file);
            free(newOne);
            return false;
        }
        // strcpy(word field of node, src word)
        strcpy(newOne->word, word);           
        index = hash(word);              
        countWords++;
        newOne->next = table[index];   
        table[index] = newOne;         
    }
    fclose(file);
    free(word);
    return true;
}

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


node* cursor = NULL;
node* tmp = NULL;

// Unloads dictionary from memory, returning true if successful else false
bool unload(void)
{
    for (int i = 0; i < N; i++)    // going through the hashtable
    {
        cursor->next = table[i];  
        tmp = cursor;             
        while (cursor != NULL)
        {
            cursor = cursor->next;
            free(tmp);
            tmp = cursor;
        }
    free(table[i]);
    }
    return true;  
}

Where is the mistake ? I searched around 60 pages of this issue and I couldn't figure it out yet! Thank you!

1
  • This program does not compile in the IDE (or check50). First error in IDE:

    dictionary.c:28:13: error: implicit declaration of function 'hash' is invalid in C99 [-Werror,-Wimplicit-function-declaration] int x = hash(word); // going to the index in the table ^

  • The hash function returns -70 for the word "a". Suggest restoring the distro hash function until other kinks are worked out.

  • This free(word); in load will give seg fault, because word is not allocated (malloc'd or calloc'd). It is declared as a char array and does not need to be (cannot be) free'd.

  • if cursor is set to NULL, as here node* cursor = NULL; in check, this cursor->next = table[x]; will give segfault, because NULL has no "members". You want cursor to be the head of the list; this node* cursor = table[x] will accomplish that.

Correcting those things will help you make progress. It is likely time to use debug50. If you call speller with the small dictionary, you could step through the debugger line by line (that's really not practical with the large dictionary :).

You must log in to answer this question.

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