好吧,所以我正在努力研究这个刽子手程序,当我用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.
我无法弄清楚如何解决未初始化的价值问题,因为我不知道我做了什么使它未初始化。
答案 0 :(得分:0)
您为list
分配了一个元素,而不是InitDictionary()
中从文件中读取的项目。因此,当您转向list
中ChooseRandom()
中的最后一个非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++;
}
也就是说,使用本地数组进行读取。只有在读取新行后才能为新数组分配。