【问题标题】:vector-related segmentation fault向量相关的分段错误
【发布时间】:2012-03-07 19:13:44
【问题描述】:
void offer_help();
bool play_one_game();

int main() {

    offer_help();

    play_one_game();

}


void offer_help() {

    int help_response;

    cout << "Need help? (0/1) ";
    cin >> help_response;
    if (help_response == 1)
    cout << "I will generate a pattern of 4 numbers, each in the range 0 through 9.\n Each guess that you enter will be a line containing 4 integers,\n separated by spaces, such as:\n\t 2 4 7 1\n FOr each guess, I will echo back a lost consisting of\n 0's and 1's, with a 1 in a given position meaning that\n  you guessed the number, and a zero meaning that you didn't.\n For example, if the actual solution was 2 3 6 1, I'll respond\n\t 1 0 0 1\n See how many guesses it takes you to get the solution!\n\n If you want to give up, type a negative number for one of\n your guesses, and we'll tell you what the pattern was.\n\n";

}

bool play_one_game() {

    srand(time(0)); //needed to start randint

    vector<int> solution; //vector of 4 randomly generated
                 //solutions
    vector<int> guess; //vector containing user guesses.
    vector<int> result;

    int guess_input;

    for(int i = 0; i < solution.size(); ++i)
    solution[i] = randint(10);

    int trial_number = 0; //int that shows what guess the user is on

    while (play_one_game() == true) {    
    //ask user for inputs.
        cout << "Guess #" << ++trial_number << "? ";
        for (int i = 0; i < guess.size(); ++i){
            cin >> guess_input;
            guess.push_back(guess_input);
        }

        //outputs error if user inputs a letter.
    if (!cin) {
        cerr << "Bad input data! Feed me numbers!\n";
        return 43;
    }
    if (cin < 0){
        cout << "Too bad! Solution was " << endl;
        for(int i = 0; i < result.size(); i++)
        cout << (result[i]);
    }

    //determines if user correctly guessed any of the
    //numbers and tells the user which is correct.
    for (int i = 0; i < result.size(); i++) {
        if (guess[i]==solution[i])
        cout << 1 << " ";
        else if (guess[i]!=solution[i])
        cout << 0 << " ";
    }
    cout << endl;

    // playagain();
    cout << endl << "Play again (0/1)? ";
    int replay;
    cin >> replay;
    if (replay == 0) {
        play_one_game() == false;
        return 5;
    }
    else if (replay == 1)
        play_one_game() == true;
    else {
        cerr << "wat?\n";
        return 10;    
    }
    }
}

这旨在让玩家猜测随机数的模式。

不知道为什么会出现分段错误。该程序应该调用 offer_help 函数,然后调用 main 函数中的 play_one_game 函数。然后它应该询问玩家是否想再玩一次。如果否,则 bool play_one_game 应设置为 false 并退出。

这与 play_one_game bool 函数有关。

【问题讨论】:

  • 检查边界——你正在迭代到result.size(),但访问guess[i]solution[i]

标签: c++ random vector segmentation-fault


【解决方案1】:

您遇到了分段错误,因为您最终会在以下行中无限递归:

while (play_one_game() == true) {

play_one_game 将在这一行调用play_one_game,这将在同一行再次调用play_one_game。这最终会导致堆栈溢出。

最好改用bool keepPlaying;while(keepPlaying)

编辑:嗯,这不仅仅是一个简单的答案,但我喜欢游戏,所以...看看下面的代码:

#include <iostream>
#include <ctime>
#include <cstdlib>
#include <vector>

bool play_one_game();

void offer_help() {
    int help_response;
    std::cout << "Need help? (0/1) ";
    std::cin >> help_response;
    if (help_response == 1)
        std::cout << "I will generate a pattern of 4 numbers, each in the range 0 through 9.\n"
            "Each guess that you enter will be a line containing 4 integers,\n"
            "separated by spaces, such as:\n"
            "\t 2 4 7 1\n"
            "For each guess, I will echo back a lost consisting of\n"
            "0's and 1's, with a 1 in a given position meaning that\n"
            "you guessed the number, and a zero meaning that you didn't.\n"
            "For example, if the actual solution was 2 3 6 1, I'll respond\n"
            "\t 1 0 0 1\n"
            "See how many guesses it takes you to get the solution!\n\n"
            "If you want to give up, type a negative number for one of\n"
            "your guesses, and we'll tell you what the pattern was.\n\n";
}

int main() {
    offer_help();
    srand(time(0)); // Initialize random numbers with current time as seed
    while(play_one_game()); // if play_one_game returns true, play again
}

bool play_one_game() {
    std::vector<int> solution(4); // Four solutions for our guessing game
    std::vector<int> guess;          // User guesses

    for(unsigned i = 0; i < solution.size(); ++i)
        solution[i] = rand() % 10;

    int trial_number = 0; //int that shows what guess the user is on
    bool keepPlaying = true;
    while(keepPlaying){
        std::cout << "Guess #" << ++trial_number << "? ";

        guess.clear(); // Clear old guesses
        for(unsigned i = 0; i < solution.size(); ++i){
            int guess_input;
            //outputs error if user inputs a letter.
            if (!(std::cin >> guess_input)) {
                std::cerr << "Bad input data! Feed me numbers!\n";
                std::cerr << "Try again!" << std::endl;
                std::cin.clear(); // Clear flags
                continue;
            }
            if (guess_input < 0){
                std::cout << "Too bad! Solution was " << std::endl;
                for(unsigned i = 0; i < solution.size(); i++)
                    std::cout << (solution[i]);
                keepPlaying = false;
                break;
            }else
                guess.push_back(guess_input);
        }
        if(!keepPlaying)
            break;
        if(solution.size() != guess.size()){
            std::cerr << "Wrong number of guesses, try again!" << std::endl;
            continue;
        }
        //determines if user correctly guessed any of the
        //numbers and tells the user which is correct.
        bool correct = true;
        for (unsigned i = 0; i < solution.size(); i++) {
            if (guess[i] == solution[i])
                std::cout << 1 << " ";
            else{
                correct = false;
                std::cout << 0 << " ";
            }
        }
        if(correct){
            std::cout << "Congratulations - you won!" << std::endl;
            break;
        }
        std::cout << std::endl;
    }
    int replay = -1;
    do{
        // Ask user for input until input is 0 or 1
        std::cout << std::endl << "Play again (0/1)? ";
        std::cin >> replay;
    }
    while(replay != 0 && replay != 1);
    return static_cast<bool>(replay); // return user replay answer (false/true)
}

Try to keep your code as simple as possible。欢迎来到 SO。 别指望未来的答案会那么夸张。

【讨论】:

  • 是的!堆栈溢出。还有像play_one_game() == false这样的电话。
【解决方案2】:

您永远不会在解决方案向量中插入任何内容。你只需声明向量,然后说:

for(int i = 0; i < solution.size(); ++i)
  solution[i] = randint(10);

...因为此时solution.size() == 0,它不会做任何事情。稍后,当您迭代结果向量时,您最终会访问空解向量中的无效元素。您也不能假设结果向量和解向量的大小相同。

【讨论】:

    猜你喜欢
    • 2020-04-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-01-16
    • 2019-11-10
    相关资源
    最近更新 更多