I have completed pset5 and passed check50.
But when i run it with valgrind, it is showing the following errors:-
==12042== Memcheck, a memory error detector
==12042== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==12042== Using Valgrind-3.10.1 and LibVEX; rerun with -h for copyright info
==12042== Command: ./speller texts/austinpowers.txt
==12042==
==12042== Conditional jump or move depends on uninitialised value(s)
==12042== at 0x4011EA: load (dictionary.c:101)
==12042== by 0x40087D: main (speller.c:40)
==12042== Uninitialised value was created by a heap allocation
==12042== at 0x4C2AB80: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==12042== by 0x400FE3: createnode (dictionary.c:21)
==12042== by 0x4011F4: load (dictionary.c:103)
==12042== by 0x40087D: main (speller.c:40)
==12042==
==12042== Use of uninitialised value of size 8
==12042== at 0x4011E1: load (dictionary.c:101)
==12042== by 0x40087D: main (speller.c:40)
==12042== Uninitialised value was created by a heap allocation
==12042== at 0x4C2AB80: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==12042== by 0x400FE3: createnode (dictionary.c:21)
==12042== by 0x4011F4: load (dictionary.c:103)
==12042== by 0x40087D: main (speller.c:40)
==12042==
==12042== Invalid read of size 8
==12042== at 0x4011E1: load (dictionary.c:101)
==12042== by 0x40087D: main (speller.c:40)
==12042== Address 0xa1 is not stack'd, malloc'd or (recently) free'd
==12042==
==12042==
==12042== Process terminating with default action of signal 11 (SIGSEGV)
==12042== Access not within mapped region at address 0xA1
==12042== at 0x4011E1: load (dictionary.c:101)
==12042== by 0x40087D: main (speller.c:40)
==12042== If you believe this happened as a result of a stack
==12042== overflow in your program's main thread (unlikely but
==12042== possible), you can try to increase the size of the
==12042== main thread stack using the --main-stacksize= flag.
==12042== The main thread stack size used in this run was 8388608.
==12042==
==12042== HEAP SUMMARY:
==12042== in use at exit: 78,291,032 bytes in 349,512 blocks
==12042== total heap usage: 349,512 allocs, 0 frees, 78,291,032 bytes allocated
==12042==
==12042== LEAK SUMMARY:
==12042== definitely lost: 0 bytes in 0 blocks
==12042== indirectly lost: 0 bytes in 0 blocks
==12042== possibly lost: 0 bytes in 0 blocks
==12042== still reachable: 78,291,032 bytes in 349,512 blocks
==12042== suppressed: 0 bytes in 0 blocks
==12042== Reachable blocks (those to which a pointer was found) are not shown.
==12042== To see them, rerun with: --leak-check=full --show-leak-kinds=all
==12042==
==12042== For counts of detected and suppressed errors, rerun with: -v
==12042== ERROR SUMMARY: 3 errors from 3 contexts (suppressed: 0 from 0)
Segmentation fault
It seems to show that I am using uninitialized data although I am setting the values to NULL in createnode() function.
And there also seems to be some issue with unload() as it shows that I am not able to free any of the allocated memory.
/**
* Implements a dictionary's functionality.
*/
#include <stdbool.h>
#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
#include "dictionary.h"
// Root Node
node *root = NULL;
// Tracks No. of words in dictionary
int words = 0;
node *createnode(void)
{
// allocate memory for new node
node* new_node = (node*) malloc(sizeof(node));
new_node->is_word = false;
// set all pointers to NULL
for (int i = 0; i < 27; i++)
new_node->children[i] = NULL;
return new_node;
}
/**
* Returns true if word is in dictionary else false.
*/
bool check(const char *word)
{
node *trav = root;
int c;
int i = 0;
do
{
// Reads characters of words one by one
c = word[i];
// change to lowercase
if(c <= 90 && c >= 65)
{
c += 32;
}
// Only allows alphabets or apostrophe
if((c >= 97 && c <= 122) || (c == '\''))
{
if(trav->children[c - 96] == NULL)
{
return false;
}
else
{
trav = trav->children[c - 96];
}
}
i++;
}while(c != '\0');
return trav->is_word;
}
/**
* Loads dictionary into memory. Returns true if successful else false.
*/
bool load(const char *dictionary)
{
// open input file
FILE *dict = fopen(dictionary, "r");
if(dict == NULL)
{
printf("File doesn't exist.\n");
return false;
}
char c;
// memory aloocation to root node
root = createnode();
// Node trav to tranverse through the linked list
node *trav = root;
do
{
c = fgetc(dict);
if(isalpha(c) || c == '\'')
{
// Checks if the node already exists or not
if(trav->children[c-96] == NULL)
{
trav->children[c-96] = createnode();
}
trav = trav->children[c-96];
}
else if(c == '\n')
{
// Sets is_word to true when we reach end of the word
trav->is_word = true;
words++;
trav = root;
}
}while(c != EOF);
fclose(dict);
return true;
}
/**
* Returns number of words in dictionary if loaded else 0 if not yet loaded.
*/
unsigned int size(void)
{
return words;
}
bool delnode(node *trav)
{
// calls function delnode on every node in node's children
for(int i = 0; i < 27; i++)
{
if(trav->children[i] != NULL)
{
return delnode(trav->children[i]);
}
}
free(trav);
return true;
}
/**
* Unloads dictionary from memory. Returns true if successful else false.
*/
bool unload(void)
{
// calls recursive function delnode
return delnode(root);
}
I have no idea where I am going wrong and so could really use some help.