找不到未初始化的值导致valgrind问题

时间:2014-03-09 04:11:07

标签: valgrind

好吧,所以我正在努力研究这个刽子手程序,当我用valgrind检查时,我继续得到条件跳转或移动取决于我的strcpy和未初始化的值 这是标题源文件:

#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);
}

这是主文件本身:

#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;
}

这是valgrind输出:

==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.

我无法弄清楚如何解决未初始化的价值问题,因为我不知道我做了什么使它未初始化。

1 个答案:

答案 0 :(得分:0)

您为list分配了一个元素,而不是InitDictionary()中从文件中读取的项目。因此,当您转向listChooseRandom()中的最后一个非NULL指针时,它会尝试走向未初始化数组的末尾。

恕我直言,我会按如下方式设置list

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++;
}

也就是说,使用本地数组进行读取。只有在读取新行后才能为新数组分配。