Can't find uninitialised values causing valgrind issues

385 views Asked by At

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.

1

There are 1 answers

1
timrau On

You allocated one more element for list than the items read from file in InitDictionary(). Thus, when you going toward the last non-NULL pointer in list in ChooseRandom(), it tried to go toward the end of an uninitialized array.

IMHO, I would set up list as follows:

int size = 0;
char buf[50];
list = malloc(50*sizeof(char*));
while(fgets(buf, 49, fp)){
    list[size] = malloc(50 * sizeof(char));
    for(ln=0;buf[ln]!='\0';ln++){
        list[size][ln] = buf[ln];
    }
    list[size][ln] = '\0';
    --ln;
    if (list[size][ln] == '\n')
        list[size][ln] = '\0';
    size++;
}

That is, use a local array for reading. Allocate for new array only after a new line is read.