如何修复C ++错误分配中的运行时错误

时间:2019-05-30 01:08:42

标签: c++ runtime-error

我已经使用类编写了一个代码,它可以执行并运行,但是当我收到此消息时,完整的main并没有执行:

libc++abi.dylib: terminating with uncaught exception of type std::bad_alloc: std::bad_alloc
Abort trap: 6

直到“处理剩余的卡:”部分的末尾执行代码,然后我收到错误消息。 我不确定为什么会这样,这是我的代码:

class CardSet
{
    public:
        CardSet();
        CardSet(int);
        ~CardSet();
        int Size() const;
        bool IsEmpty() const;
        void Shuffle();
        int Deal();
        void Deal(int,CardSet&,CardSet&);
        void Deal(int,CardSet&,CardSet&,CardSet&,CardSet&);
        void AddCard(int);
        void MergeShuffle(CardSet&);
        void Print() const;
    private:
        int* Card;
        int nCards;
};

void PrintCard(int);

void PrintCard(int c)
{
    int Rank = c%13;
    int Suit = c/13;
    const char NameSuit[5] = "SCDH";
    const char NameRank[14] = "23456789XJQKA";
    cout << NameRank[Rank] << NameSuit[Suit];
}


/*Default constructor that sets up a set of 0 cards*/
CardSet::CardSet()
{
    Card = NULL;
    nCards = 0;
}

/*Initialising constructor where the number of cards is the argument passed*/
CardSet::CardSet(int c)
{
    nCards=c;
    Card = new int[c]; /*Create memory in the array using the new operator*/
        for(int i = 0; i < c; i++) /*for loop to set each value*/
    {
    Card[i] = (i % 52); /*Uses mod operator to ensure number of cards never exceeds 51*/
    }
}

/*Destructor that deletes/cleans up the memory previously set in the array*/
CardSet::~CardSet()
{

    if (Card!=NULL)

        delete [] Card;

    Card = NULL;
}

/*If cardset is empty bool returns true*/
bool CardSet::IsEmpty() const
{
     if (Size() == 0) /*If the set of cards is empty*/

        return true;

    else

        return false;
}

/*Print function passes cards to PrintCard function to print out the contents of the set, 24 cards to a line*/
void CardSet::Print() const
{
    for (int i = 0; i < nCards; i++) /*Prints out the cards from i = 0 to i = ncards*/

    {
        if (i%24 == 0 && i != 0) /*when it hits the 24th card, start a new line*/
            cout << endl;

        else
            cout << " "; /*else enters space between cards*/

        PrintCard(Card[i]);
    }
    cout << endl; /*New line*/

}

/*Returns the number of cards in the set*/                                                                                           
int CardSet::Size() const
{

    return nCards;

}

/*rearranges the cards in the set in a random manner*/
void CardSet::Shuffle()
{

    int temp;

    for (int i = 0; i < nCards; i++){

        int j = rand() % (nCards - 1);

        if (i != j){

            temp = Card[i];

            Card[i] = Card[j];

            Card[j] = temp;

        }

    }

}

/*takes current set and set provided as an argument and makes current set contain contain all the cards from the two sets*/
void CardSet::MergeShuffle(CardSet& set)
{
    while(set.IsEmpty()==false){

        int dealCard = set.Deal();

        AddCard(dealCard);
    }

    Shuffle(); /*call to shuffle function*/

}

/*add a card to the current hand*/ 
void CardSet::AddCard(int c)
{
int *hand;

    hand = new int[nCards+1]; /*memory allocation to hand*/


    for(int i = 0; i<nCards; i++){ /*for each card i in the set nCards*/

        hand[i] = Card[i];

    }

    hand[nCards] = c;

    delete [] Card; /*delete memory in the array*/

    Card = hand;

    nCards++;
}

/*return the value of the first card in the set which is located in the 0th element of the array*/
int CardSet::Deal()
{
 int *nDeck;

    int temp = 0;

    nDeck = new int[nCards-1]; /*Make fresh memory*/

    temp = Card[0]; /*temp is the first card which we are returning*/



    if (IsEmpty()){ /*If the set is empty*/

        cout << "This set is empty." << endl;

        return -1;

    }

    int j = 0;

    for (int i = 1; i < nCards; i++){

        nDeck[j] = Card[i]; /*Move the old memory to new memory*/

        j++;

    }

    delete []Card; /*Delete the old memory*/

    Card=nDeck;


    nCards--;

    return temp; /*return the value of the first card*/
}

/*deals two hands in the two CardSet arguments passed*/
void CardSet::Deal(int c,CardSet& set1,CardSet& set2)
{
    for (int i = 0; i < c; i++){

        int dealCard = Deal(); /*Deal a card from the original deck*/

        set1.AddCard(dealCard); /*Add it to the 1st set argument passed*/

        dealCard = Deal(); /*Deal another card*/

        set2.AddCard(dealCard); /*Add it to the 2nd set argument passed*/

    }
}

/*deals four hands in the four CardSet arguments passed*/
void CardSet::Deal(int c,CardSet& set1,CardSet& set2,CardSet& set3,CardSet& set4)
{
    for (int i = 0; i < c && IsEmpty()==false; i++){

        int dealCard = Deal(); /*Deal a card from the original deck*/

        set1.AddCard(dealCard); /*Add it to the 1st set argument passed*/

        dealCard = Deal(); /*Deal another card*/

        set2.AddCard(dealCard); /*Add it to the 2nd set argument and so on for 3rd and 4th set*/

        dealCard = Deal();

        set3.AddCard(dealCard);

        dealCard = Deal();

        set4.AddCard(dealCard);

    }
}

这是我的主要爱好:

int main()
{
    cout << "BEGINNING OF CARDSET TESTS . . .  "<< endl << endl;

    //--------- STEP 1 TESTS ---------------------------------------------------

    cout << "Testing constructors, Print(), Size() & IsEmpty():" << endl;
    CardSet CardSet1; // empty cCardSet
    CardSet CardSet2(12); // CardSet with 12 cards
    if(CardSet1.IsEmpty()) cout<<"CardSet1 is empty"<<endl;
    else cout<<"CardSet1 has "<< CardSet1.Size() <<" cards" << endl;
    if(CardSet2.IsEmpty()) cout<<"CardSet2 is empty"<<endl;
    else cout<<"CardSet2 has "<< CardSet2.Size() <<" cards" << endl;
    cout << "Printout of CardSet1: ";
    CardSet1.Print();
    cout << "Printout of CardSet2: ";
    CardSet2.Print();
    cout << endl;

    /*--------- STEP 2 TESTS ---------------------------------------------*/

    cout << "Testing Normal Shuffle: "<< endl;
    CardSet CardSet3(24); // CardSet with 24 cards
    cout << "Unshuffled CardSet: ";
    CardSet3.Print();
    CardSet3.Shuffle();
    cout << "Shuffled CardSet:   ";
    CardSet3.Print();
    cout << endl;

    cout << "Testing Merge Shuffle: "<< endl;
    CardSet CardSet4(12); // CardSet with 12 cards
    cout<<"CardSet1 has "<< CardSet2.Size() <<" cards and cardSet2 has "<< CardSet4.Size() <<" cards" << endl;
    cout << "Printout of CardSet1: ";
    CardSet2.Print();
    cout << "Printout of CardSet2: ";
    CardSet4.Print();
    cout << "Merge shuffling both CardSets into CardSet1:\n";
    CardSet2.MergeShuffle(CardSet4);
    cout<<"CardSet1 has "<< CardSet2.Size() <<" cards and cardSet2 has "<< CardSet4.Size() <<" cards" << endl;
    cout << "Printout of CardSet1: " ;
    CardSet2.Print();
    cout << "Printout of CardSet2: ";
    CardSet4.Print();
    cout << endl;

    cout << "Testing Adding and removing cards to a CardSet:"<< endl;
    cout << "CardSet Size: " << CardSet2.Size() << endl;
    cout << "Printout of CardSet: ";
    CardSet2.Print();
    int Card = CardSet2.Deal();
    cout << "Dealing 1 card: ";
    PrintCard(Card);
    cout << endl;
    cout << "CardSet Size: " << CardSet2.Size() << endl;
    cout << "Adding card: ";
    PrintCard(Card);
    cout << endl;
    CardSet2.AddCard(Card);
    cout << "CardSet Size: " << CardSet2.Size() << endl;
    cout << "Printout of CardSet: ";
    CardSet2.Print();
    cout << endl;

    cout << "Testing Dealing out cards from one CardSet into two other CardSets:" << endl;
    CardSet CardSet5,CardSet6(6); // CardSets with 0 & 6 cards
    cout << "Printout of CardSet1: ";
    CardSet2.Print();
    cout << "Printout of CardSet2: ";
    CardSet5.Print();
    cout << "Printout of CardSet3: ";
    CardSet6.Print();
    cout << "Dealing 3 Cards from CardSet1 into CardSet2 and CardSet3: " << endl;
    CardSet2.Deal(3,CardSet5,CardSet6);
    cout << "Printout of CardSet1: ";
    CardSet2.Print();
    cout << "Printout of CardSet2: ";
    CardSet5.Print();
    cout << "Printout of CardSet3: ";
    CardSet6.Print();
    cout << endl;

    cout << "Testing Dealing out cards from one CardSet into four other CardSets:" << endl;
    CardSet CardSet7,CardSet8(6); // CardSets with 0 & 6 cards
    cout << "Printout of CardSet1: ";
    CardSet2.Print();
    cout << "Printout of CardSet2: ";
    CardSet5.Print();
    cout << "Printout of CardSet3: ";
    CardSet6.Print();
    cout << "Printout of CardSet4: ";
    CardSet7.Print();
    cout << "Printout of CardSet5: ";
    CardSet8.Print();
    cout << "Dealing 3 cards from CardSet1 into CardSet2 and CardSet3: " << endl;
    CardSet2.Deal(3,CardSet5,CardSet6,CardSet7,CardSet8);
    cout << "Printout of CardSet1: ";
    CardSet2.Print();
    cout << "Printout of CardSet2: ";
    CardSet5.Print();
    cout << "Printout of CardSet3: ";
    CardSet6.Print();
    cout << "Printout of CardSet4: ";
    CardSet7.Print();
    cout << "Printout of CardSet5: ";
    CardSet8.Print();
    cout << "Dealing out remaining cards: " << endl;
    CardSet2.Deal(3,CardSet5,CardSet6,CardSet7,CardSet8);
    cout << "Printout of CardSet1: ";
    CardSet2.Print();
    cout << endl;

    cout << ". . . END OF TESTS"<< endl;

    return 0;
}


任何帮助将不胜感激。

2 个答案:

答案 0 :(得分:2)

Deal中,首先调用nDeck = new int[nCards-1],然后再调用几行IsEmpty()。如果您要处理的卡片组为空,则分配将调用new int[0-1],即new int[-1],由于要分配的元素数是无符号的,因此在系统上它将为new int[0xFFFFFFFF]与32位整数。这将超出您可能分配的大小,从而导致异常。

答案 1 :(得分:2)

您正在int CardSet::Deal()函数中分配内存:

nDeck = new int[nCards - 1]; /*Make fresh memory*/

nCards变为零。我想nCards为零时必须终止程序。