Visual Studio中函数调用和函数的第一行之间的代码损坏问题

问题描述 投票:1回答:2

我正在使用Visual Studio编译和运行纸牌游戏。我的问题似乎是当我调用函数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);
}

[当我使用调试器运行此代码时,我可以在实时变量中看到A行card1具有有效的卡值...variable view

当我到达B行时,card1现在已损坏。corrupted variable view

任何想法?

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;                
}

我认为我发现了这个问题,请参阅下文...正在测试

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;                
}

这就是问题...我要归还卡而不是指针。谢谢大家的帮助!

更新:由于此处未解决的问题,我现在甚至进一步更改了代码]

  1. 我已将我的私人卡向量更改为卡指针向量,并使用new将其推入向量指针。
  2. cards.push_back (new Card(suit,name,value,symbol,file));
    
  1. 这意味着我的函数现在是指针类型:
  2. 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);
    }
    

这似乎已经解决了我遇到的问题。由于地址是存储和传递的地址,因此每张卡也只允许一个副本。

有人看到我可能需要知道的其他东西吗?

谢谢!

我正在使用Visual Studio编译和运行纸牌游戏。我的问题似乎是当我调用函数get_top_card()void Deck :: shuffle(){//此函数会打乱卡片组时。甲板tempdeck; ...

c++ visual-studio-2017 fltk
2个回答
0
投票

问题出在我的顶级卡功能上。


0
投票

第一版:


0
投票

第一版:

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;                
}

无效,因为您返回对范围结束的对象top_card的引用。这一个存储在堆栈中,可以轻松覆盖。另外,CPU可能会检查是否正在访问堆栈顶端上方的内存,从而导致崩溃。

此版本也是非法的:

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;                
}

因为这一次,您返回对位于堆上的矢量尖端的引用,所以减小了矢量的大小。这是未定义的行为。

这是可行的,因为在这种情况下,向量缓冲区不被重新分配,只是向量的大小减小了一个。结果,引用指向有效的内存(这可以防止崩溃),但是它仍然是缓冲区溢出错误。

最可能解决它的正确方法是从返回类型中掺杂参考:

Card Deck::get_top_card()deck
{
    Card top_card = cards[cards.size()-1];
    erase_card(cards.size()-1);
    return top_card;                
}

我怀疑您的Card是复杂类型,很可能可以廉价地复制到周围。

© www.soinside.com 2019 - 2024. All rights reserved.