malloc和总线10运行时错误帮助C.

时间:2014-01-07 05:26:57

标签: c malloc free

所以我正在进行一项特定的编程任务,我认为需要使用我不熟悉的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 %s\n", computerChoice);
    printf("%s\n", 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 %s\n", computerChoice);
    printf("%s\n", outcome);
    return 0;
}

所以,非常感谢每个人的评论。我已经在代码上修复了一些问题,它似乎正在编译并运行而没有错误。现在,我正在试图找出何时free() malloced内存。我显然无法在返回后释放它,但我需要返回值。

我会将其复制到char然后释放分配的原始内存吗?

再次感谢

4 个答案:

答案 0 :(得分:0)

您不需要使用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);
}

然后在主要内部使用它...

char uChoice[128];
getUserChoice(uChoice);

答案 1 :(得分:0)

You picked paper wins.. // why is it saying "You picked paper wins.."
char* compare(char* choice1, char* choice2)中,你对选择1和选择2执行strcat() 因此在打印之前会修改userChoice的内容。

同样在char* getComputerChoice()中,你应该strcpy()或strncpy()将字符串复制到新的malloced空间,而不是=,后者是分配字符串文字,这就是为什么有时你会出现Segmentation fault ,因为如果计算机获胜,你的程序将尝试strcat choice2,这是不允许字符串文字。

答案 2 :(得分:0)

虽然你应该免费使用malloc内存,是的,问题就在这里

if(randChoice == 0)

    cpuChoice = "rock"; //use strcpy(cpuChoice,"rock");

else if (randChoice == 1)
    cpuChoice = "paper"; // strcpy(cpuChoice,"paper");
else
    cpuChoice = "scissors"; // strcpy(cpuChoice,"scissors");

答案 3 :(得分:0)

由于每次跑步都会优先玩游戏一次。你可以使用while循环你可以从用户那里继续输入或不使用开关等。下面我只包括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 %s\n", computerChoice);
              outcome = compare(userChoice, computerChoice);



              printf("%s\n", outcome);
        }
        return 0;
} 

在这种情况下,您的代码会调用malloc n次,这将导致不必要的内存创建。如果使用很多,最终可能会使程序崩溃,因为你还没有释放内存。

所以释放内存总是有益的,也是更好的编码方式。

对于未定义的行为,使用相同的userchoice指针并与函数

中的结果连接
            char* compare(char* choice1, char* choice2) 

要避免这种情况,你可以移动你的“printf(”你选择%s。\ n“,userChoice)” 在“userChoice = getUserChoice();”之后如上所示在代码中

并使用strcpy()复制函数中的字符串char * getComputerChoice()