简体   繁体   中英

Runtime error while generating object's values in the constructor of an object that aggregates them

I'm writing a C++ program for an introductory course that simulates a poker game. I created a card object with with integers to store a value for face and suit. I then created a DeckOfCards object that has a C++11 array of 52 card objects. I am attempting to assign the cards their values and shuffle the deck in the deckOfCards constructor. After putting it through some tests I believe i've tracked the issue down to this face and suit generation process. I'm also attempting to share these objects with another class (Hand) by returning a reference to these objects in a dealCard() method, but I think the errors are occurring before the hand is instantiated. The error is occurring in GCC on my Arch-Linux VM and in Visual Studio, so it seems to be compiler indepedent (though clang wont even compile it). The Deck's Constructor:

DeckOfCards::DeckOfCards(bool startShuffled) //Constructor.
{
    /************************************************************
    Constructor iterates through the four suits and 13 faces,
    generating a card for each combination. This adds up to a
    deck of 52 unique cards. By default it shuffles the deck to
    prevent accidental usage of an unshuffled deck in a card
    game. Passing 'false' as an arguement prevents the initial
    shuffle.
    ************************************************************/
    int arrayLoc = 0; //The card being initialized (its a subscript of deck).

    for (int i = 0; i < 4; i++) //For each of the four suits.
    {
        for (int j = 0; j < 13; j++) //For each face in that suit.
        {
            deck[arrayLoc].setFace(j); //Create a card with that face.
            deck[arrayLoc].setSuit(i); //And with that suit.
            arrayLoc++; //Then move to the next card.
        }
    }

    currentCard = 0; //Sets the top of the deck.

    if (startShuffled)
        shuffle(); //Shuffles the deck by default.
}

VS2013's debugger is saying it can't read deck[0]'s face and suit data after the first iteration through this loop. It is acting similarly for the rest of them as well. The main program itself (not shown here) is running up to the point where I attempt to deal the cards to a Hand via an array of pointers to the deck, and I think its related to incorrect initialization during deck generation. I can provide more of the code if no one can find a problem with what I have here.

Card's getters/setters:

void Card::setFace(int faceVal)
{
    if (faceVal >= 0 && faceVal < 13) //Validates value before setting.
        face = faceVal; //Sets the value of Card's face.
    else
        throw invalid_argument("Face value must be between 0 and 12 (inclusive)");
}

void Card::setSuit(int suitVal)
{
    if (suitVal >= 0 && suitVal < 4) //Validates value before setting.
        suit = suitVal; //Sets the value of Card's suit.
    else
        throw invalid_argument("Suit value must be between 0 and 3 (inclusive)");
}

//Getters
int Card::getFace() const //Returns face by value.
{
    return face;
}

int Card::getSuit() const //Returns suit by value.
{
    return suit;
}

EDIT: (Adding info) My hand class has an array of five pointers to Card objects, which It retrieves from the deck by calling the DeckOfCard's dealCard() method.

const Card DeckOfCards::dealCard()
{
    /*************************************************
    If the deck has not depreciated, this returns a
    const reference to the card at the top of the deck
    and increments to the next card. If it is depreciated
    it throws an exception.
    *************************************************/
    if (moreCards())
    {
        unsigned int tempCurrentCard = currentCard;
        currentCard++;
        return deck[tempCurrentCard];
    }
    else
    {
        throw invalid_argument("The deck is out of unused cards. Must shuffle to continue.");
    }
}

The Hand's constructor:

Hand::Hand(const Card &card1, const Card &card2, 
    const Card &card3, const Card &card4, const Card &card5)
{
    /*****************************************************
    Constructor initializes a c++11 array of pointers to
    card objects.
    *****************************************************/

    //Initialize the cards in hand. (as pointers)
    cardsInHand[0] = &card1;
    cardsInHand[1] = &card2;
    cardsInHand[2] = &card3;
    cardsInHand[3] = &card4;
    cardsInHand[4] = &card5;

    //Calculate the value of the hand.
    calcHandScore();
}

I'm instantiating the hand in main by using myDeck.dealCard() as each of the arguments in the hand's constructor. This data hand-off seems like a likely place for the error to be. Hand player1(deck.dealCard(), deck.dealCard(), deck.dealCard(), deck.dealCard(), deck.dealCard()); But It could also be related to the shuffling algorithm for the deck:

void DeckOfCards::shuffle()
{
    /***********************************************************
    Shuffles the deck of cards by via a random number generator.
    Should be called whenever the current card is the final
    card in the deck.
    ***********************************************************/
    srand(time(NULL)); //Creates a random seed for number generation.
    int randomValue; //Stores random number for card selection.

    //Loops through each card in deck and swaps it with another.
    for (int i = 0; i < 52; i++) //Iterates through the deck.
    {
        randomValue = rand() % 51; //Selects a random card to swap.

        if (randomValue != i) //Prevents self assignment.
        {
            //Swaps the cards values, effectively swapping their locations.
            int tempFace = deck[randomValue].getFace(); //Holds a copy of selected card.
            int tempSuit = deck[randomValue].getSuit();
            deck[randomValue].setFace(deck[i].getFace());
            deck[randomValue].setSuit(deck[i].getSuit());
            deck[i].setFace(tempFace);
            deck[i].setSuit(tempSuit);
        }
    }

    currentCard = 0; //Shuffle resets the "top" of the deck.
}

This is going to sound stupid but after stepping through the code with the debugger I realized the class logic was all sound. The issue was with a for loop inside another for loop incrementing the wrong variable (ie for (int j = 5; i < 52; j++) ).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM