C++ visual studio中函数调用和函数第一行之间的代码损坏问题

C++ visual studio中函数调用和函数第一行之间的代码损坏问题,c++,visual-studio-2017,fltk,C++,Visual Studio 2017,Fltk,我正在使用VisualStudio编译和运行一个纸牌游戏。我的问题似乎是在调用函数get_top_card()时 当我使用调试器运行此代码时,我可以在活动变量中看到第1行上的card1具有有效的card值。。。 当我到达B线时,卡1现在已损坏。。 有什么想法吗 Card& Deck::get_top_card() //returns the top card and removes it from the deck { Card top_card = car

我正在使用VisualStudio编译和运行一个纸牌游戏。我的问题似乎是在调用函数get_top_card()时

当我使用调试器运行此代码时,我可以在活动变量中看到第1行上的card1具有有效的card值。。。

当我到达B线时,卡1现在已损坏。。

有什么想法吗

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;                
}
这就是问题所在…我是在回一张卡片,而不是指针。 谢谢大家的帮助

更新: 由于这里没有提到的问题,我现在对代码做了进一步的修改

  • 我已经将我的私人卡向量更改为卡指针向量,并使用新的
  • 这意味着我的函数现在是指针类型:
  • 这似乎解决了我遇到的问题。因为地址是存储和传递的,所以它也只允许每张卡有一份副本

    有人看到我需要注意的其他事情吗


    谢谢大家!

    问题出在我的“获取顶级卡片”功能中

    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;                
    }
    
    更新: 这似乎是一个更好的答案:

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

    问题在于我的“获取顶级卡片”功能

    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;                
    }
    
    更新: 这似乎是一个更好的答案:

    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;                
    }
    
    
    第一版:

    Card&Deck::get_top_Card()//返回顶卡并将其从卡组中移除
    {
    Card top_Card=cards[cards.size()-1];//持有卡片
    擦除卡(cards.size()-1);//将其从卡组中删除
    返回最上面的卡片;
    }
    
    无效,因为您正在返回对范围结束的对象
    top\u card
    的引用。这一个存储在堆栈上,可以很容易地重写。此外,CPU可能会检查堆栈顶端上的内存访问是否导致崩溃

    此版本也是非法的:

    Card&Deck::get_top_Card()
    {
    Card&top_Card=cards[cards.size()-1];//需要创建引用。
    擦除卡(cards.size()-1);
    返回最上面的卡片;
    }
    
    因为这一次您返回了对位于堆上的向量尖端的引用,所以您减小了向量的大小。这是未定义的行为

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

    最合适的修复方法可能是使用返回类型的引用:

    卡片组::获取顶部卡片()卡片组
    {
    卡片顶部\卡片=卡片[cards.size()-1];
    擦除卡(cards.size()-1);
    返回最上面的卡片;
    }
    
    我怀疑您的
    卡是一种复杂的类型,很可能可以便宜地复制。

    第一版:

    Card&Deck::get_top_Card()//返回顶卡并将其从卡组中移除
    {
    Card top_Card=cards[cards.size()-1];//持有卡片
    擦除卡(cards.size()-1);//将其从卡组中删除
    返回最上面的卡片;
    }
    
    无效,因为您正在返回对范围结束的对象
    top\u card
    的引用。这一个存储在堆栈上,可以很容易地重写。此外,CPU可能会检查堆栈顶端上的内存访问是否导致崩溃

    此版本也是非法的:

    Card&Deck::get_top_Card()
    {
    Card&top_Card=cards[cards.size()-1];//需要创建引用。
    擦除卡(cards.size()-1);
    返回最上面的卡片;
    }
    
    因为这一次您返回了对位于堆上的向量尖端的引用,所以您减小了向量的大小。这是未定义的行为

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

    最合适的修复方法可能是使用返回类型的引用:

    卡片组::获取顶部卡片()卡片组
    {
    卡片顶部\卡片=卡片[cards.size()-1];
    擦除卡(cards.size()-1);
    返回最上面的卡片;
    }
    

    我怀疑你的
    卡是一种复杂的类型,很可能可以便宜地复制。

    请提供。我的水晶球说
    get\u top\u Card()
    实现中有一个bug。你的
    这个
    变量在这两个屏幕截图中是不同的。看起来您在不同的时间点对不同的
    Deck
    对象进行操作。因此,在调用
    tempdeck.add_card_to_Deck
    this->add_card_to_Deck
    之间发生的任何事情都可能是罪魁祸首。狩猎快乐!F11是做什么的?这是一个步骤吗?请提供。我的水晶球显示
    get\u top\u card()
    实现中有一个错误。您的
    变量在这两个屏幕截图中都不同。看起来您在不同的时间点对不同的
    Deck
    对象进行操作。因此,在调用
    tempdeck.add_card_to_Deck
    this->add_card_to_Deck
    之间发生的任何事情都可能是罪魁祸首。狩猎快乐!F11是做什么的?这是一步吗?这仍然是错误和未定义的行为。由于
    erase_卡(cards.size()-1),它似乎可以工作不会覆盖存储卡的内存块。感谢您的指导。这仍然是错误和未定义的行为。由于
    erase_卡(cards.size()-1),它似乎可以工作不会覆盖存储卡的内存块。感谢您的指导。复制它时我遇到的问题是,每个卡都有多个图像和其他图形属性,在复制时表现不好。这就是为什么我一开始就试图改变它的行为。复制它时我遇到的问题是,每张卡都有多个图像和其他图形属性,它们在被复制时表现不好
    
    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;                
    }