Okay, so I'm trying to work on this hangman program, and when I check it with valgrind i keep getting Conditional jump or move depends on uninitialized value(s) with my strcpy and Here is the header source file:
#include "randword.h"
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
static char **list;
void InitDictionary(char* name){
int size=0, ln;
FILE *fp = fopen(name, "r");
list = (char**)malloc(50*sizeof(char*));
*list = (char*)malloc(50*sizeof(char));
while(fgets(*(list+size), 49, fp)){
for(ln=0;*(*(list+size)+ln)!='\0';ln++){}
ln=ln-1;
if (*(*(list+size)+ln) == '\n')
*(*(list+size)+ln) = '\0';
size++;
*(list+size) = (char*)malloc(50*sizeof(char));
}
fclose(fp);
}
void ChooseRandomWord(char** word){
int randIndex,num;
for(num=0;*(list+num)!=NULL;num++){}
srand(time(NULL));
randIndex = rand() % (num-1);
strcpy(*word, *(list+randIndex));
for(;num>=0;num--)
free(*(list+num));
free(list);
}
and here is the main file itself:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "randword.h"
int main(){
char *word, *reveal, guess;
int guesses = 8,i,x,index,correct=0,istrue;
reveal = (char*)malloc(50*sizeof(char));
word = (char*)malloc(50*sizeof(char));
InitDictionary("words.txt");
ChooseRandomWord(&word);
for(x=0;*(word+x)!='\0';x++){
*(reveal+x)='-';
}
printf("Welcome to Hangman!\nI will guess a secret word. On each turn, you guess\na letter. If the letter is in the secret word, I\nwill show you where it appears; if not, a part of\nyour body gets strung up on the scaffold. The\nobject is to guess the word before you are hung.\n");
while(guesses>0){
istrue=0;
printf("Your word now looks like this: %s\nYou have %d guesses left.\n", reveal, guesses);
printf("Guess a letter: ");
scanf("%c", &guess);
getchar();
guess = toupper(guess);
for(index=0;*(word+index)!='\0';index++){
if(*(word+index)==guess){
if(*(word+index)==*(reveal+index)){
istrue=2;
break;
}
else{
istrue=1;
*(reveal+index)=*(word+index);
correct++;
}
}
}
if(istrue==2){
printf("You have already guessed %c.\n",guess);
}
else if(istrue){
printf("That is correct.\n");
}
else{
printf("There are no %c's in the word.\n", guess);
guesses--;
}
if(*(word+correct)=='\0'){
printf("You guessed the word: %s.\n", reveal);
free(reveal);
free(word);
return 0;
}
}
printf("You have run out of guesses and lost.\n");
free(word);
free(reveal);
return 0;
}
here is the valgrind output:
==5319== Conditional jump or move depends on uninitialised value(s)
==5319== at 0x80487F1: ChooseRandomWord (in /home/ulr146/GOZA_hw4/randword)
==5319== by 0x80488CB: main (in /home/ulr146/GOZA_hw4/randword)
==5319== Uninitialised value was created by a heap allocation
==5319== at 0x4026FDE: malloc (vg_replace_malloc.c:207)
==5319== by 0x80486E3: InitDictionary (in /home/ulr146/GOZA_hw4/randword)
==5319== by 0x80488C0: main (in /home/ulr146/GOZA_hw4/randword)
==5319==
==5319== Conditional jump or move depends on uninitialised value(s)
==5319== at 0x4025DBD: free (vg_replace_malloc.c:323)
==5319== by 0x804885E: ChooseRandomWord (in /home/ulr146/GOZA_hw4/randword)
==5319== by 0x80488CB: main (in /home/ulr146/GOZA_hw4/randword)
==5319== Uninitialised value was created by a heap allocation
==5319== at 0x4026FDE: malloc (vg_replace_malloc.c:207)
==5319== by 0x80486E3: InitDictionary (in /home/ulr146/GOZA_hw4/randword)
==5319== by 0x80488C0: main (in /home/ulr146/GOZA_hw4/randword)
Welcome to Hangman!
I will guess a secret word. On each turn, you guess
a letter. If the letter is in the secret word, I
will show you where it appears; if not, a part of
your body gets strung up on the scaffold. The
object is to guess the word before you are hung.
==5319==
==5319== Conditional jump or move depends on uninitialised value(s)
==5319== at 0x40276F7: strlen (mc_replace_strmem.c:242)
==5319== by 0x406F6D7: vfprintf (vfprintf.c:1581)
==5319== by 0x4075B5F: printf (printf.c:35)
==5319== by 0x8048923: main (in /home/ulr146/GOZA_hw4/randword)
==5319== Uninitialised value was created by a heap allocation
==5319== at 0x4026FDE: malloc (vg_replace_malloc.c:207)
==5319== by 0x80488A2: main (in /home/ulr146/GOZA_hw4/randword)
Your word now looks like this: ----
You have 8 guesses left.
Guess a letter: d
That is correct.
Your word now looks like this: D---
You have 8 guesses left.
Guess a letter: a
That is correct.
Your word now looks like this: DA-A
You have 8 guesses left.
Guess a letter: t
That is correct.
==5319==
==5319== Conditional jump or move depends on uninitialised value(s)
==5319== at 0x40276F7: strlen (mc_replace_strmem.c:242)
==5319== by 0x406F6D7: vfprintf (vfprintf.c:1581)
==5319== by 0x4075B5F: printf (printf.c:35)
==5319== by 0x8048A3E: main (in /home/ulr146/GOZA_hw4/randword)
==5319== Uninitialised value was created by a heap allocation
==5319== at 0x4026FDE: malloc (vg_replace_malloc.c:207)
==5319== by 0x80488A2: main (in /home/ulr146/GOZA_hw4/randword)
You guessed the word: DATA.
==5319==
==5319== ERROR SUMMARY: 6 errors from 4 contexts (suppressed: 13 from 1)
==5319== malloc/free: in use at exit: 0 bytes in 0 blocks.
==5319== malloc/free: 10 allocs, 10 frees, 952 bytes allocated.
==5319== For counts of detected errors, rerun with: -v
==5319== All heap blocks were freed -- no leaks are possible.
I can't quite figure out how to fix the uninitialized value issues because I don't know what I did that made it uninitialized.
You allocated one more element for
listthan the items read from file inInitDictionary(). Thus, when you going toward the last non-NULL pointer inlistinChooseRandom(), it tried to go toward the end of an uninitialized array.IMHO, I would set up
listas follows:That is, use a local array for reading. Allocate for new array only after a new line is read.