Home > Software design >  Why do I keep getting this error: exception Unhandled : Unhandled exception thrown: read access viol
Why do I keep getting this error: exception Unhandled : Unhandled exception thrown: read access viol

Time:01-19

I am currently working on the BlackJack project, but there is an error showing "exception Unhandled: Unhandled exception thrown: read access violation. this was 0x4.". I am not quite sure which part I did wrong, and the program sometimes runs normally sometimes shows that exception. In draw_card function, it returns a value of a random number. For example: if we get 13, the value will be 10. It also returns the name of the card and the type of the card such as 13 corresponds to king.

int main()
{
    srand(time(0));
    unsigned bet;
    int player = 0 , dealer = 0;
    string card , type;

    cout << "You have $100. Enter bet: ";
    cin >> bet;
    
    cout << "Your cards are:" << endl; 
    player  = draw_card(card, type, player);
    cout << "  " card   " of "   type << endl;
    player  = draw_card(card, type, player);
    cout << "  "   card   " of "   type << endl << endl << endl;
}

int draw_card(string& card, string& type, int drawer_points) {
    int randomNumber;  //between 1 and 13
    int suite;         //between 1 and 4 to determine the suite of the card.

    randomNumber = rand() % 13   1;
    suite = rand() % 4   1;
    
    card = getRank(randomNumber);
    type = getSuit(suite);

    if (randomNumber == 13 || randomNumber == 12 || randomNumber == 11) {
        return 10;
    }else if (randomNumber == 1) {
        int ace1 = 21 - (drawer_points   1);
        int ace2 = 21 - (drawer_points   11);

        return ace1 < ace2 ? 1 : 11;
    }
    else
    {
        return randomNumber;
    }
}


string getSuit(int suit) {
    
    switch (suit)
    {
    case 0:
        return "spades";
        break;
    case 1:
        return "clubs";
        break;
    case 2:
        return "diamonds";
        break;
    case 3:
        return "hearts";
        break;
    default:
        break;
    }
    
}

string getRank(int rank) {
    switch (rank)
    {
    case 13:
        return "King";
        break;
    case 12:
        return "Queen";
        break;
    case 11:
        return "Jack";
        break;
    case 1:
        return "Ace";
        break;
    case 2:
        return "Two";
        break;
    case 3:
        return "Three";
        break;
    case 4:
        return "Four";
        break;
    case 5:
        return "Five";
        break;
    case 6:
        return "Six";
        break;
    case 7:
        return "Seven";
        break;
    case 8:
        return "Eight";
        break;
    case 9:
        return "Nine";
        break;
    case 10:
        return "Ten";
        break;
    default:
        break;
    }

CodePudding user response:

You generate

suite = rand() % 4   1;

This is a random number between 1 and 4 inclusive.

You then call

getSuit(suite);

But getSuit only has switch branches for values between 0 and 3 inclusive:

switch (suit)
{
case 0:
    return "spades";
    break;
case 1:
    return "clubs";
    break;
case 2:
    return "diamonds";
    break;
case 3:
    return "hearts";
    break;
default:
    break;
}

Not returning a value from a function that is declared to return a value is undefined behaviour.

CodePudding user response:

A few functions like getSuit and getRank in your code don't return a value if only the default case of their switch statement is executed.

You can return an empty string in the default cases:

default:
        return ""; // empty string

And in the call site, check to see if the returned value is empty using the empty function.

Another way is to use std::optional<T> like below:

std::optional<string> getSuit( const int suit )
{
    switch (suit)
    {
    case 0:
        return "spades";
    case 1:
        return "clubs";
    case 2:
        return "diamonds";
    case 3:
        return "hearts";
    default:
        return { }; // empty optional
    }
}

And in the call site:

std::optinal<std::string> type { getSuit(suite) };

if ( type ) // if optional has value
{
    // extract and use the value inside of optional
    type.value( );
}

Keep in mind that if the optional does not have a value, using value() will throw. You can use value_or() instead which does not throw.

  •  Tags:  
  • Related