After getting my code to work, i looked if there were any memory leaks using valgrind. It found no memory leaks, however it returned these two errors:
==7109== Conditional jump or move depends on uninitialised value(s)
==7109== at 0x4C32D08: strlen (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==7109== by 0x40138D: check (dictionary.c:154)
==7109== by 0x400C39: main (speller.c:112)
==7109== Uninitialised value was created by a heap allocation
==7109== at 0x4C2FB0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==7109== by 0x40119B: load (dictionary.c:88)
==7109== by 0x400914: main (speller.c:40)
After searching online, I discovered the calloc method that initializes the pointer given by malloc to 0. After using it in my code, I got no more errors in valgrind, but i don't understand why? I don't understand what calloc()
is doing that malloc()
isn't. I understand that calloc does the same as malloc but initializes the memory block to 0.
Thanks in advance,
My code (load function):
// 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)
{
// Create a node with the current word
node *element = malloc(sizeof(node)); // allocate memory for a new node
// Check if node was created sucessfully
if (element == NULL)
{
printf("Error creating node\n");
return false;
}
// Initialize current node
add_word(element, word); // Adds the current dict word to the node
element->next = NULL;
node structure:
typedef struct node
{
char word[LENGTH + 1];
struct node *next;
}
node;
add_word:
// Adds a word to a node's value (word)
int add_word(node *element, const char *word)
{
if (element == NULL)
{
printf("Node is invalid");
return 1;
}
for (int i = 0; word[i] != '\0'; ++i)
{
element->word[i] = word[i];
}
// Success
return 0;
}
add_word
do? Does it use thenext
member before you set it toNULL
?next
obviously was the wrong thought by me, asstrlen
was involved (totally missed that). Should have guessed "missing null terminator" immediately. Thanks for adding the code, made it easier to see the mistake.