Before starting explaining my issue, I know there are threads talking about Conditional jump or move depends on uninitialised value(s)
errors prompted after executing Valgrind but unfortunately, none of them helped me fixing my problems.
Also, I've already asked a question about this pset a few months ago, feel free to check it here as it fully described how I designed my code (I'll sum up the main parts of it below).
Long story short, I've done this pset a while ago, it works but I don't know why, I've totally skipped the Valgrind part... I'm currently revising all my psets before submitting them and well, when I came to verify pset5 and executed Valgrind, I had 9911860 errors reported... Not bad! :)
Last thing, I've read again and again these two threads:
valgrind messages about “unititialised value(s)” - are they an issue?
Both are treating Conditional jump or move depends on uninitialised value(s)
issues and I'm sure I'm missing something very important over there, I've even posted a comment in the last one a few days ago but no answer came unfortunately.
OK so I've declared my node as it follows
//dictionary.h
typedef struct node
{
bool is_word;
struct node* children[27];
}
node;
At the top of my dictionary.c sheet, I've declared as global variables
node* root;
node* newptr;
Later in the load function, I call root
like this:
root = (struct node*) malloc(sizeof(node));
for (int i = 0; i < 27; i++)
{
root->children[i] = NULL;
}
I've taken the idea of the for loop from Kareem's answer in Valgrind error in PSET6 topic except I didn't write root**[i]**->children[i] = NULL;
as I can't compile my code then, I need to replace ->
by a dot... and my errors count sees a rise of 25 errors (9911860)!
Removing the index to root
helped me to reduce the number of errors to 9911833, a 27 errors drop that totally makes sense to me.
Later in the load
function, I declare newptr
to be the next nodes in my trie:
node* newptr = (struct node*) malloc(sizeof(node));
This declaration comes in the loop that iterates through each character in the dictionary, inside the if statement checking if the end of the word in the dictionary has been reached.
If I apply the same method of initialization used for root
, something like this for instance
node* newptr = (struct node*) malloc(sizeof(node));
for (int i = 0; i < 27; i++)
{
newptr->children[i] = NULL;
}
The errors count doesn't drop.
Talking about newptr
, I use this node as it follows:
if (isalpha(letter))
{
if (newptr->children[letter - 'a'] == NULL)
{
newptr->children[letter - 'a'] = (struct node*) malloc(sizeof(node));
}
newptr = newptr->children[letter - 'a'];
}
Valgrind points out every lines like if (newptr->children[word[i] - 'a' == NULL)
and newptr->children[letter - 'a'] = (struct node*) malloc(sizeof(node));
to be the source of the errors. Even the declaration of the node newptr
itself is identified as an error.
If I pull this loop
for (int i = 0; i < 27; i++)
{
newptr->children[i] = NULL;
}
or this
newptr->children[word[i] - 'a'];
before
newptr = newptr->children[letter - 'a'];
my errors count collapses to 2 or 3 errors but my code can't compile anymore due to a Segmentation Fault (core dumped)
.
Can someone please help me or at least explain me why the "NULL initialization loop" works for the root
node but never works for the newptr
node.
If more pseudo or chunks of my code are needed to understand my problem, please tell me and I'll edit my question.
root
is the root node of my trie andnewptr
is the node used for all the other nodes coming after the root node in my trie. Bothroot
andnewptr
use the samestruct node
and both are now declared as global, at the top of my dictionary.c sheet code. In my first attempts, it is true that onlyroot
was declared as global but declaringnewptr
as global too hasn't improved anything. I edit right now my question as I forgot to mention that bothroot
andnewptr
are now global. – DFATPUNK Nov 12 '15 at 8:31