I tried to solve problem with memory usage but did not figure out where is the problem.
Dictionary unloads successfully but still issue with memory access exists.
I think that problem with dictionary_list, where words are saved from dictionary before add them to table.
I tried the following:
free
dictionary_list
before each read from dictionary:if (dictionary_list != NULL) { free(dictionary_list); } I observed strange behaviour in
table[]
only the last word is saved, while all other words are deleted. For example, simple dictionary:
aa
a
bb
b
c
when a is saved into table[0] it has correct values:
table[0] -> word = a
table[0] -> next -> word = aa
When bb is saved, I got the following in the table[]
table[0] -> word = bb
table[0] -> next -> word = bb
table[1] -> word = bb
I don't understand why it happens, I free dictionary_list
only one last read from dictionary.
For table
I made link to the memory and table
should save all links between the same hashes but by some reason during each reading new link is changed for all hashes.
For variable dictionary_list
malloc is used - it is mandatory to free it, but
if (table[hash_value] == NULL)
{
table[hash_value] = malloc(sizeof(node));
if (table[hash_value] == NULL)
{
// todo
return false;
}
// todo
}
else
{
// todo
}
check50 returns error:
A
cat
is
a
caterpillar
cATTT
IS
A
caterPillar
avv
free(): double free detected in tcache 2
Aborted
- free the all links in dictionary_list
if (dictionary_list != NULL)
{
for (node *temp = dictionary_list; temp != NULL; temp = temp -> next)
{
node *n_temp = NULL;
if (temp != NULL)
{
// todo
}
}
}
spellcheckers fails in the beginning:
free(): double free detected in tcache 2
Aborted
- If do not free dictionary_list I got valgrind error:
==4963== LEAK SUMMARY:
==4963== definitely lost: 0 bytes in 0 blocks
==4963== indirectly lost: 0 bytes in 0 blocks
==4963== possibly lost: 0 bytes in 0 blocks
==4963== still reachable: 56 bytes in 1 blocks
==4963== suppressed: 0 bytes in 0 blocks
==4963==
==4963== For lists of detected and suppressed errors, rerun with: -s
==4963== ERROR SUMMARY: 87 errors from 6 contexts (suppressed: 0 from 0)
dictionary.c
// Implements a dictionary's functionality
#include <stdbool.h>
#include "dictionary.h"
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
#include "ctype.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 = 26;
// Hash table
node *table[N];
// global variable dictionary - each function will have access to the values from that variable
node *dictionary_list = NULL;
// vocabulary size
int vac_size = 0;
// Returns true if word is in dictionary, else false
bool check(const char *word)
{
// TODO
free(small_case_word);
return false;
}
// Hashes word to a number
unsigned int hash(const char *word)
{
// TODO
// hash value generates only for first letter
// all words which are started with the same letter are linked to that letter
int hash_value = 0;
hash_value = tolower(word[0]) - 97;
// check hash_value generation
// printf("hash_value: %d \n", hash_value);
return hash_value;
}
// Loads dictionary into memory, returning true if successful, else false
bool load(const char *dictionary)
{
// TODO
FILE *read_dictionary = fopen(dictionary, "r");
if (read_dictionary == NULL)
{
printf("Could not open file.\n");
return false;
}
char *read_symbol = malloc(46 * sizeof(char));
if (read_symbol == NULL)
{
return false;
}
unsigned int hash_value = 0;
// node *temp_dictionary_list = NULL;
while (fscanf(read_dictionary, "%s", read_symbol) != EOF)
{
// printf("read_symbol: %s \n", read_symbol);
hash_value = hash(read_symbol);
dictionary_list = malloc(sizeof(node));
if (dictionary_list == NULL)
{
free(dictionary_list);
fclose(read_dictionary);
return false;
}
strcpy(dictionary_list -> word, read_symbol);
dictionary_list -> next = NULL;
if (table[hash_value] == NULL)
{
//TODO
}
vac_size++;
// free(temp_dictionary_list);
// free(dictionary_list);
}
free(read_symbol);
fclose(read_dictionary);
return true;
}
// Returns number of words in dictionary if loaded, else 0 if not yet loaded
unsigned int size(void)
{
// TODO
// vocabulary size is calculating in load funcition
// vac_size is global variable
// just return the value
return vac_size;
}
// Unloads dictionary from memory, returning true if successful, else false
bool unload(void)
{
// TODO
// node *temp = NULL;
// unload function should free all variables
// but by some reason it does not work
for (int i = 0; i <= N; i++)
{
if (table[i] != NULL)
{
//todo
}
}
return true;
}
valgrind summary:
==4963== Invalid read of size 8
==4963== at 0x401E70: unload (dictionary.c:232)
==4963== by 0x401768: main (speller.c:153)
==4963== Address 0x4b9a740 is 48 bytes inside a block of size 56 free'd
==4963== at 0x483CA3F: free (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==4963== by 0x401C1D: load (dictionary.c:155)
==4963== by 0x4012CE: main (speller.c:40)
==4963== Block was alloc'd at
==4963== at 0x483B7F3: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==4963== by 0x401C27: load (dictionary.c:157)
==4963== by 0x4012CE: main (speller.c:40)
==4963==
WORDS MISSPELLED: 2
WORDS IN DICTIONARY: 14
WORDS IN TEXT: 12
TIME IN load: 0.03
TIME IN check: 0.00
TIME IN size: 0.00
TIME IN unload: 0.00
TIME IN TOTAL: 0.04
==4963==
==4963== HEAP SUMMARY:
==4963== in use at exit: 56 bytes in 1 blocks
==4963== total heap usage: 40 allocs, 45 frees, 11,496 bytes allocated
==4963==
==4963== 56 bytes in 1 blocks are still reachable in loss record 1 of 1
==4963== at 0x483B7F3: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==4963== by 0x401C27: load (dictionary.c:157)
==4963== by 0x4012CE: main (speller.c:40)
==4963==
==4963== LEAK SUMMARY:
==4963== definitely lost: 0 bytes in 0 blocks
==4963== indirectly lost: 0 bytes in 0 blocks
==4963== possibly lost: 0 bytes in 0 blocks
==4963== still reachable: 56 bytes in 1 blocks
==4963== suppressed: 0 bytes in 0 blocks
==4963==
==4963== For lists of detected and suppressed errors, rerun with: -s
==4963== ERROR SUMMARY: 87 errors from 6 contexts (suppressed: 0 from 0)
Thank you in advance!