Search code examples
c++visual-studio-2017fltk

Code corruption issue between function call and first line of function in visual studio


I am using visual studio to compile and run a card game. My issue seems to be when I call a function get_top_card()

void Deck::shuffle(){
    //This function shuffles the deck.
    Deck tempdeck;                                      
    while (cards.size() > 0)                            
    {
        int cardnumber = -1;                            
        cardnumber = rand() % cards.size();             
        tempdeck.add_card_to_deck(cards[cardnumber],false); 
        erase_card(cardnumber);                         
    }
    while (tempdeck.size() >0){                         
        add_card_to_deck(tempdeck.get_top_card(),false);   //error occurs in this function
    }
}


void Deck::add_card_to_deck(Card& card1, bool shift){       //Lets call this line A
    if (face_up) card1.set_face_up();                       //Lets call this line B
    else card1.set_face_down();
    Point new_location(decklocation.x , decklocation.y + cards.size() * 25);
    if (shift) card1.move_card(card1.location(), new_location);
    else card1.move_card(card1.location(), decklocation);
    card1.button()->hide();
    cards.push_back(card1);
}

When I am running this code using the debugger I can see in the live variables that on line A card1 has a valid card value... variable view

When I get to line B the card1 is now corrupted.. corrupted variable view

Any Ideas?

Card& Deck::get_top_card()          //returns the top card and removes it from the deck
{
    Card top_card = cards[cards.size()-1];      //holds the card
    erase_card(cards.size()-1);                 //deletes it from the deck
    return top_card;                
}

I think I found the issue see below...testing now

Card& Deck::get_top_card()          //returns the top card and removes it from the deck
{
    Card& top_card = cards[cards.size()-1];     //holds the card
    erase_card(cards.size()-1);                 //deletes it from the deck
    return top_card;                
}

That was the issue...I was returning a card and not the pointer. Thank you all for your help!

Update: I have changed the code even further now due to issues that were eluded to here

  1. I have changed my private cards vector to a vector of Card pointers and I push them into the vector using new.
cards.push_back (new Card(suit,name,value,symbol,file));
  1. This means that my functions are now pointer types:
Card* Deck::get_top_card()          //returns the top card and removes it from the deck
{
    Card* top_card = cards[cards.size()-1];     //holds the card
    cards.erase(cards.end()-1);                 //deletes it from the deck
    return top_card;                
}

void Deck::add_card_to_deck(Card* card, bool shift){        //adds a card to the bottom of the deck.
    if (face_up) card->set_face_up();
    else card->set_face_down();
    Point new_location(decklocation.x , decklocation.y + cards.size() * 25);
    if (shift) card->move_card(card->location(), new_location);
    else card->move_card(card->location(), decklocation);
    card->button()->hide();
    cards.push_back(card);
}

This seems to have solved the issues that I was having. It also allows for only one copy of each card since the address is what is stored and passed.

Does anyone see anything else I might need to be aware of?

Thank you!


Solution

  • The issue was in my get top card function.

    Card& Deck::get_top_card()          
    {
        Card& top_card = cards[cards.size()-1];     //needed to create a reference.
        erase_card(cards.size()-1);                 
        return top_card;                
    }
    

    Update: This seems to be a better answer:

    void Deck::add_card_to_deck(Card* card, bool shift){        //adds a card to the bottom of the deck.
        if (face_up) card->set_face_up();
        else card->set_face_down();
        Point new_location(decklocation.x , decklocation.y + cards.size() * 25);
        if (shift) card->move_card(card->location(), new_location);
        else card->move_card(card->location(), decklocation);
        card->button()->hide();
        cards.push_back(card);
    }
    
    Card* Deck::get_top_card()          //returns the top card and removes it from the deck
    {
        Card* top_card = cards[cards.size()-1];     //holds the card
        cards.erase(cards.end()-1);                 //deletes it from the deck
        return top_card;                
    }