2014-01-07 21 views
-2

所以我有一個特定的編程任務,我正在努力,我相信需要使用我不熟悉的malloc()函數。我的理解是,如果您使用malloc(),則必須在完成使用時釋放內存,否則最終會出現奇怪的行爲。我想知道這是爲什麼我每隔一段時間都會遇到總線10運行時錯誤?Malloc和總線10運行時錯誤幫助C

這個任務是寫一個石頭剪刀紙遊戲,這就是我想出的。

#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然後釋放分配的原始內存?

再次感謝

+0

'cpuChoice = 「foo」 的複製串;',內存泄漏。使用strcpy或類似的東西爲你的男子空間。並且你在getComputerChoice()中追蹤你的字符串,所以你在第一個結果中獲得** win **。如果電腦贏了,你正在做strcat字符串,所以seg故障。 – moeCake

+0

你可以擴展更多關於strcat字符串文字的東西嗎?我認爲這是該計劃的主要問題,因爲我拿出來了,而且我再也沒有遇到巴士錯誤。 – user2948847

+0

[strcat](http://www.cplusplus.com/reference/cstring/strcat/)將修改** destination **的內容,因此您不能將字符串字面量作爲第一個參數傳遞。 Malloced space可以,但是你搞砸了getComputerChoice()。 – moeCake

回答

0

您不需要使用malloc。只需將一個字符指針傳遞給該方法而不是返回一個。

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); 
+0

感謝您的回覆。所以,你說什麼總是有道理的。唯一的問題是我不能改變返回類型(需要返回一個char *)。 – user2948847

+0

然後,只需返回選擇。如果你不能改變方法的簽名,那麼我猜malloc是你唯一的選擇。 – chasep255

0

You picked paper wins.. // why is it saying "You picked paper wins.."
char* compare(char* choice1, char* choice2)然後使用這樣的主內......,你做的strcat()來選擇1和選擇2。
因此,在打印它之前,userChoice的內容會被修改。

而且在char* getComputerChoice(),你應該的strcpy()或函數strncpy()來複制字符串到新malloced空間,而不是=,後來是分配字符串文字,這就是爲什麼有時你得到段錯誤,因爲如果計算機勝,你程序會嘗試strcat選擇2,這是不允許字符串文字。

0

雖然你應該使用免費的malloc內存和肯定的問題是在這裏

如果(randChoice == 0)

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

else if (randChoice == 1) 
    cpuChoice = "paper"; // strcpy(cpuChoice,"paper"); 
else 
    cpuChoice = "scissors"; // strcpy(cpuChoice,"scissors"); 
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次,這會導致不必要的內存創建。最終可能會因爲你沒有釋放內存而使你的程序崩潰。

所以釋放內存總是有益的,更好的編碼方式。

而對於不確定的行爲UR使用相同的userchoice指針,在功能上與結果串聯

  char* compare(char* choice1, char* choice2) 

避免這種U可以將您的 「printf(」 你挑%S。\ n 「userChoice)」 「userChoice = getUserChoice();」之後的 如上所示的int代碼

,還可以使用的strcpy(),用於在所述功能字符* getComputerChoice()