繁体   English   中英

使用向量的C ++纸牌 <Card*> vector.erase函数错误

[英]C++ solitaire using vector<Card*> error with the vector.erase function

我用C ++制作了一个非常简单的纸牌。 牌组随机洗牌,我拿一张牌,然后按顺序依次王牌,一,二,...,十,杰克,皇后,国王。 如果该卡正好是我的读音,请从卡座中取出该卡。 我使用剩余的卡座来重复此过程,直到取出卡或卡座为空(仅在这种情况下我才赢)。 这是我编写的代码,但是在使用功能擦除功能删除卡时,第62行出现错误。 我不明白这是问题所在。

#include <iostream>
#include <vector>
using namespace std;

enum SUIT { HEART, CLUB, DIAMOND, SPADE };
string suit_string[] = {"HEART", "CLUB", "DIAMOND", "SPADE"};

enum VALUE { ACE, TWO, THREE, FOUR, FIVE, SIX,
    SEVEN, EIGHT, NINE, TEN, JACK, QUEEN, KING};
string value_string[] = {"ACE", "TWO", "THREE", "FOUR", "FIVE",
    "SIX", "SEVEN", "EIGHT","NINE", "TEN", "JACK", "QUEEN", "KING"};

class Card {
 public:
    Card(SUIT s, VALUE v);
    SUIT suit;
    VALUE value;
    string toString();
};

Card::Card(SUIT s, VALUE v){
    suit=s;
    value=v;
}

string Card::toString(){
    return value_string[(int)this->value]+" of "+suit_string[(int)this->suit];
}



int main() {
        vector<Card*> deck;
        for (int i=0; i<4; i++) {
            for (int j=0; j<13; j++) {
                deck.push_back(new Card((SUIT)i,(VALUE)j));
            }               
        }

        int removed_count, runs = 0;

        do{
            random_shuffle(deck.begin(),deck.end());
            removed_count=0;

            cout<<"--- Run number: "<<++runs<<"\n";
            cout<<"--- still "<<deck.size()<<" cards in the deck\n";

            for (int i=0; i<4; i++) {
                for (int j=0; j<13; j++) {
                    //cout<<i*13+j<<"\n";

                    int position=i*13+j; //from 0 to 51

                    cout<<"'"+value_string[j]+"'"<<" <-> ";

                    Card card=*(deck.at(position));
                    cout<<card.toString()<<" ";

                        if(card.value == j){
                            removed_count++;
                            deck.erase(deck.begin()+position); //problems here!
                            cout<<"removed\n";
                        }else{
                            cout<<"not removed\n";
                        }

                    }               
            }
            if(deck.empty()) break;
        }while(removed_count>0);

        if(deck.empty()){
            cout<<"You win!\n";
        }else{
            cout<<"You lose!\n";
        }

        return 0;
}

好吧,当我启动它时,我得到了

'KING' <-> terminate called after throwing an instance of 'std::out_of_range'
  what():  vector::_M_range_check

显然,这意味着您正在尝试访问矢量边界之外的内容。 您正在擦除循环中的一个元素:

deck.erase(deck.begin()+position);

命中之后,向量的大小将是51而不是52。但是,您的循环正在处理52个值,正如您在此注释中清楚提到的那样:

int position=i*13+j; //from 0 to 51

因此,在删除项目并在甲板中剩余51个项目(0到50)之后,最后一次迭代仍将尝试访问第51个元素并崩溃。 它失败的实际行是这一行:

Card card=*(deck.at(position));

当状态为以下时: 在此处输入图片说明

如您所见,向量中有51个元素,并且*(deck.at(position))将尝试访问第52个元素(由于从零开始计数,索引为51),并引发异常。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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