我从文件中读取单词并将其传递给二叉树时出现问题。当我调试它时,它说:
if (characterquality == "Slayer"){
int HP = 150;
int Attack = 75;
int Defense = 50;
int MP = 20;
int EXP = 0;
int Gold = 50;
boolean firstbattle = true;
while (firstbattle){
int firstbattlehealth = HP;
int firstbattleattack = Attack;
int firstbattledefense = Defense;
int firstbattleMP = MP;
int firstbattleEXP = EXP;
int firstbattlegold = Gold;
int firstattack = (int) Math.ceil(Math.random() * 6);
int firstdefense = (int) Math.ceil(Math.random() * 6);
int firstenemyattack = (int) Math.ceil(Math.random() * 6);
int firstenemydefense = (int) Math.ceil(Math.random() * 6);
int firstenemyhealth = (int) Math.ceil(Math.random() * 50);
int firstenemyhitpoints = (int) Math.ceil(Math.random() * 25);
boolean firstkill = true;
while (firstkill) {
if (firstattack > firstenemydefense){
int firsthitpoints = (int) Math.ceil(Math.random() * firstbattleattack);
}
int firstenemynewhealth = firstenemyhealth - firsthitpoints;
if (firstenemynewhealth <= 0){
firstkill = false;
}
if (firstattack <= firstenemydefense){
System.out.println("Attack failed!");
}
if (firstenemyattack > firstdefense){
int firstenemyhitpointattack = (int) Math.ceil(Math.random() * firstenemyhitpoints);
System.out.println("The enemy did " + firstenemyhitpointattack + " damage to you. You have " + firstbattlehealth + " health remaining.");
}
if (firstenemyattack <= firstdefense){
System.out.println("Enemy attack missed!");
}
}
int firstenemynewhealth = firstenemynewhealth;
if (firstenemynewhealth <= 0){
firstbattle = false;
}
}
}
以下是源代码:
Unhandled exception at 0x76E7773B(ntdll.dll) in Projekt.exe: 0.C00000005:
Access violation reading location 0x0037902A.
答案 0 :(得分:1)
您的计划有几个问题:
zero
中,你过早释放指针,你应该将free(aTree);
作为最后一个语句移动,否则你调用未定义的行为,可能是崩溃(但不是你的那个)有,因为你从来没有称这个功能):
void zero(Tree *aTree) {
if (aTree != NULL) {
zero(aTree->left);
zero(aTree->right);
free(aTree);
}
在函数alpha
中,使用递归,其中一个简单的循环就足够了。编译器可能会将其转换为循环,但确实如此。这不是一个错误,但为什么不使用更惯用的方法,如:
int alpha(const char *word1, const char *word2) {
for (size_t i = 0;; i++) {
if (word1[i] == '\0' && word2[i] == '\0')
return 2;
if (word1[i] == word2[i])
continue;
if (word1[i] < word2[i])
return 1;
else
return 0;
}
}
在函数create
中,为字符串分配一个字节,这肯定是导致崩溃的原因。您应该分配strlen(word) + 1
或使用strdup(word)
。您不应该转换malloc()
的返回值:
Tree *create(const char *word) {
Tree *temp;
temp = malloc(sizeof(Tree));
temp->left = temp->right = NULL;
temp->val = 1;
temp->word = strdup(word);
return temp;
}
在函数insert
中,您多次调用alpha
,效率很低:您可以使用switch
语句:
Tree *insert(Tree *aTree, const char *word) {
if (aTree == NULL) {
return create(word);
switch (alpha(aTree->word, word)) {
case 0:
aTree->left = insert(aTree->left, word);
break;
case 1:
aTree->right = insert(aTree->right, word);
break;
case 2:
aTree->val++;
break;
}
}
return aTree;
}
函数main
有多个问题:
argv[1]
。如果程序在没有命令行参数的情况下运行,则为NULL
。temp
应定义为int
,您应该在使用getc()
从文件中读取字节后测试其值,这是惯用的名称c
用于此的变量。if (c >= 'A' && c <= 'Z')
适用于ASCII,这在今天几乎是通用的,但使用isupper(c)
代替它更可靠。buffer
,在插入单词之前设置'\0'
即可。fclose(fp)
为fp
时,您不应致电NULL
,这是未定义的行为。以下是更正后的版本:
int main(int argc, char *argv[]) {
Tree *myTree = NULL;
char buffer[256];
int c;
size_t i;
FILE *fp;
if (argc < 2) {
printf("missing argument\n");
return 2;
}
fp = fopen(argv[1], "r");
if (fp == NULL) {
printf("cannot open %s\n", argv[1]);
return 1;
}
i = 0;
while ((c = getc(fp)) != EOF) {
c = toupper(c);
if (isupper(c)) {
if (i < sizeof(buffer))
buffer[i] = c;
i++;
} else {
if (i > 0 && i < sizeof(buffer)) {
buffer[i] = '\0';
puts(buffer);
myTree = insert(myTree, buffer);
i = 0;
}
}
}
fclose(fp);
show(myTree);
return 0;
}