因此,我正在处理一项特定的编程任务,我认为该任务需要使用我不熟悉的malloc()
函数。我的理解是,如果你使用malloc()
,你必须在使用完它后释放内存,否则你可能会出现奇怪的行为。我想知道这是否就是为什么我每隔一段时间就会出现总线10运行时错误的原因?
任务是写一个石头剪刀纸游戏,这就是我想到的。
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
char* getUserChoice()
{
/* Prompt the user "Enter rock, paper, or scissors: " and return
the string they enter */
printf("Enter rock, paper, or scissors: ");
char * uChoice = malloc(sizeof(char) * 128);
scanf("%s", uChoice);
return uChoice;
}
char* getComputerChoice()
{
srand (time(NULL));
/* get a pseudo-random integer between 0 and 2 (inclusive) */
int randChoice = rand() % 3;
char * cpuChoice = malloc(sizeof(char) * 128);
/* If randChoice is 0, return "rock", otherwise if randChoice is 1,
return "paper", and if randChoice is 2, return "scissors". */
if (randChoice == 0)
cpuChoice = "rock";
else if (randChoice == 1)
cpuChoice = "paper";
else
cpuChoice = "scissors";
return cpuChoice;
}
char* compare(char* choice1, char* choice2)
{
/* Implement the logic of the game here. If choice1 and choice2
are equal, the result should be "This game is a tie."
Make sure to use strcmp for string comparison.*/
char * cmpChoice = malloc(sizeof(char) * 128);
int comparedValue = strcmp(choice1,choice2);
if (comparedValue == 0)
cmpChoice = "This game is a tie.";
else
{
if ((strcmp(choice1, "rock") == 0 && strcmp(choice2, "paper") == 0) ||
(strcmp(choice1,"paper") == 0 && strcmp(choice2, "scissors") == 0) ||
(strcmp(choice1, "scissors") == 0 && strcmp(choice2, "rock") == 0))
cmpChoice = strcat(choice2, " wins");
else
strcat(choice1, " wins);
}
return cmpChoice;
}
int main(int argc, char** argv)
{
char *userChoice, *computerChoice, *outcome;
userChoice = getUserChoice();
computerChoice = getComputerChoice();
outcome = compare(userChoice, computerChoice);
printf("You picked %s.n", userChoice);
printf("Computer picked %sn", computerChoice);
printf("%sn", outcome);
return 0;
}
我描述的奇怪行为是,有时输出会像这个
Enter rock, paper, or scissors: paper
You picked paper wins.. // why is it saying "You picked paper wins.."
Computer picked rock
paper wins.
而其他时候,如果不进行任何重新编译,它将是
Enter rock, paper, or scissors: scissors
Bus error: 10 // possibly due to not calling free()?
如果有人能帮我理解在我返回指针之前如何释放我分配的内存,那就太好了。显然,只使用字符串会容易得多,但需要使用char *
类型。
感谢您提供的任何帮助或见解。
使用更新的代码编辑
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
char* getUserChoice()
{
/* Prompt the user "Enter rock, paper, or scissors: " and return
the string they enter */
printf("Enter rock, paper, or scissors: ");
char * uChoice = malloc(sizeof(char) * 128);
scanf("%s", uChoice);
return uChoice;
}
char* getComputerChoice()
{
srand (time(NULL));
/* get a pseudo-random integer between 0 and 2 (inclusive) */
int randChoice = rand() % 3;
char * cpuChoice = malloc(sizeof(char) * 128);
/* If randChoice is 0, return "rock", otherwise if randChoice is 1,
return "paper", and if randChoice is 2, return "scissors". */
if (randChoice == 0)
strcpy(cpuChoice, "rock");
else if (randChoice == 1)
strcpy(cpuChoice, "paper");
else
strcpy(cpuChoice, "scissors");
return cpuChoice;
}
char* compare(char* choice1, char* choice2)
{
/* Implement the logic of the game here. If choice1 and choice2
are equal, the result should be "This game is a tie."
Make sure to use strcmp for string comparison.*/
char * cmpChoice = malloc(sizeof(char) * 128);
int comparedValue = strcmp(choice1,choice2);
if (comparedValue == 0)
strcpy(cmpChoice, "This game is a tie.");
else
{
if ((strcmp(choice1, "rock") == 0 && strcmp(choice2, "paper") == 0) ||
(strcmp(choice1,"paper") == 0 && strcmp(choice2, "scissors") == 0) ||
(strcmp(choice1, "scissors") == 0 && strcmp(choice2, "rock") == 0))
{
strcat(cmpChoice, choice2);
strcat(cmpChoice, " wins");
}
else
{
strcat(cmpChoice, choice1);
strcat(cmpChoice, " wins.");
}
}
return cmpChoice;
}
int main(int argc, char** argv)
{
char *userChoice, *computerChoice, *outcome;
userChoice = getUserChoice();
computerChoice = getComputerChoice();
outcome = compare(userChoice, computerChoice);
printf("You picked %s.n", userChoice);
printf("Computer picked %sn", computerChoice);
printf("%sn", outcome);
return 0;
}
所以,非常感谢大家的评论。我已经修复了代码上的一些地方,它似乎正在编译和运行,没有出现错误。现在,我正试图弄清楚什么时候free()
损坏的内存。很明显,我不能在归还后将其释放,但我需要归还价值。
我会把它复制到char
,然后释放分配的原始内存吗?
再次感谢
您不需要使用malloc。只需向该方法传递一个char指针,而不是返回一个。
void getUserChoice(char * choice)
{
/* Prompt the user "Enter rock, paper, or scissors: " and return
the string they enter */
printf("Enter rock, paper, or scissors: ");
scanf("%s", choice);
}
然后像这样在main内部使用。。。
char uChoice[128];
getUserChoice(uChoice);
You picked paper wins.. // why is it saying "You picked paper wins.."
在char* compare(char* choice1, char* choice2)
中,您对choice1和choice2执行strcat()操作。
因此,在打印userChoice之前,它的内容会被修改。
同样在char* getComputerChoice()
中,您应该使用strcpy()或strncpy()将字符串复制到新的mallocated空间,而不是=
,后者是指定字符串文字,这就是为什么有时您会出现Segmentation错误,因为如果计算机获胜,您的程序将尝试strcat choice2,这是不允许字符串文字的。
尽管您应该使用free for malloc内存,是的,问题就在这里
如果(randChoice==0)
cpuChoice = "rock"; //use strcpy(cpuChoice,"rock");
else if (randChoice == 1)
cpuChoice = "paper"; // strcpy(cpuChoice,"paper");
else
cpuChoice = "scissors"; // strcpy(cpuChoice,"scissors");
因为每次运行时,游戏最好玩一次以上。u可以使用while循环u可以接受用户的输入以继续或不使用内部开关等等。下面我只包含while循环。
int main(int argc, char** argv)
{
char *userChoice, *computerChoice, *outcome;
while(1)
{
userChoice = getUserChoice();
printf("You picked %s.n", userChoice);
computerChoice = getComputerChoice();
printf("Computer picked %sn", computerChoice);
outcome = compare(userChoice, computerChoice);
printf("%sn", outcome);
}
return 0;
}
在这种情况下,您的代码调用malloc n次,这将导致不必要的内存创建。如果使用太多,最终可能会导致程序崩溃,因为您没有释放内存。
因此,释放内存总是有益的,也是更好的编码方式。
对于未定义的行为,使用相同的用户选择指针并与函数中的结果连接
char* compare(char* choice1, char* choice2)
为了避免这种情况,你可以移动你的"printf"("你选择了%s。\n",userChoice)在"userChoice=getUserChoice();"之后,如上所示,插入代码
并使用strcpy()复制函数char*getComputerChoice()中的字符串