链接列表卡片组 - 访问违规读取位置

时间:2014-03-28 01:53:06

标签: c++ linked-list dynamic-allocation

所以,我试图使用链接列表为类创建一副牌,但是我很难找到我遇到错误的原因:访问冲突读取位置0x00000020。我还不熟悉编码和动态分配,我确信它很容易解决,但我不能为我的生活弄清楚。我的Deck类是链表,我的Card类是节点。制作游戏Crazy Eights的最终目标。游戏类应该有四个甲板(画堆,丢弃堆,我的手,电脑手)。

代码在deck.cpp

SIZE++;函数的addCard()处中断

加入deck.h

    #pragma once
    #include "Card.h"

    class Deck
    {
    protected:
        int SIZE;   //SIZE variable - indicates how many cards in deck
        Card *top;  //pointer to TOP of linked structure of cards

    public:
        //CONSTRUCTOR
        Deck();

        //FILL DECK
        void fill();                        //initialize the Deck to contain the standard 52 cards
        void addCard(int v, string s);      //*insert* a new card into the Deck

        //DRAW CARD
        Card *drawCard();                   //*remove* top card from the Deck and return it

        //FIND AND REMOVE
        void removeCard(int val, string s);//*find* a specific card and remove it from the Deck

        //SHUFFLE
        void shuffle();                     //randomize the order of cards in the Deck

        //PRINT
        void print();                       //displays the contents of the Deck
};

Deck.cpp

#include "Deck.h"
#include "Card.h"
#include <iostream>
using namespace std;

Deck::Deck()
{
    top = NULL;
    SIZE = 0;
}

void Deck::fill()
{
    string suit;
    for (int i = 0; i < 13; i++){
        for (int j = 0; j < 4; j++){
            switch (j){
                case 0: suit = "HEART"; break;
                case 1: suit = "DIAMOND"; break;
                case 2: suit = "CLUB"; break;
                case 3: suit = "SPADE"; break;
            }//end switch
            addCard(i, suit);
        }//end for
    }//end for
}//end fill

Card *Deck::drawCard()  
{
    Card *draw = top;
    top = top->getNext();
    SIZE--;
    return draw;
}//end drawCard

void Deck::removeCard(int val, string s)    
{
    //FINDS CARD
    Card *cur = top;
    while (cur != NULL && cur->getVALUE() != val && cur->getSUIT() != s)
        cur = cur->getNext();
    if (cur != NULL) 
        cout << cur->getVALUE() << cur->getSUIT();
    else{ 
        cout << "NOT FOUND";
        return;
    }//end else

    //REMOVES CARD
    Card *remove, *prev;
    if (top->getVALUE() == val && top->getSUIT() == s){
        remove = top;
        top = top->getNext();
        delete remove;
        SIZE--;
        removeCard(val, s);
    }//end if
    else{
        prev = top;
        while (prev->getNext() != NULL && prev->getNext()->getVALUE() != val && prev->getNext()->getSUIT() != s)
            prev = prev->getNext();
        if (prev->getNext() != NULL){
            remove = prev->getNext();
            prev->setNext(remove->getNext());
            delete remove;
            SIZE--;
            removeCard(val, s);
        }//end if
    }//end else
}//end removeCard

void Deck::addCard(int val, string s)
{
    SIZE++;
    top = new Card(val, s, top);
}//end addCard

//void Deck::shuffle()
//{
//    for (int i = 0; i < 7; i++)
//    {
//        // first break the deck into two half lists  -- like when you
//      //split the deck in half to shuffle
//        Deck half1;
//        Deck half2;
//        for (SIZE; SIZE > SIZE/2; SIZE--)
//        {
//            //draw card off the deck and add card to half1
//          SIZE--;
//        }//end for
//        for (int j = 0; j <= SIZE/2; SIZE++)
//        {
//            //draw card off the deck and add card to half2
//          SIZE++;
//        }//end for
//
//        // now repeatedly pull one card from either half1 or half2 and
//      // place it back on the deck -- like when the cards
//        // are falling back in random clumps during shuffling.
//        // we don't want to draw with 50-50 probability, instead we're
//      // going to skew the probability of selecting from
//        // each pile based on the relative size of the two piles.
//        while (/*half1 and half2 still have cards in them*/true)
//        {
//            int probPile1; //= size of half1 / (size of half1 + size of half2) * 100
//            int randomNum; //= random number between 1 and 100
//            if (randomNum <= probPile1)
//            {
//                //pull a card off half1 and add it back onto the deck
//            }//end if
//            else
//            {
//                //pull a card off half2 and add it back onto the deck
//            }//end else
//        }//end while
//  }//end for
//}//end shuffle

void Deck::print()
{
    cout << "Cards in pile: " << SIZE;
}//end print

Card.h

#pragma once
#include <string>
using namespace std;

class Card
{
    friend class Deck;  //allows Deck class access to Card's private member variables

    protected:
        int VALUE;      //value of card [1,2,3...11,12,13]
        string SUIT;    //HEART, DIAMOND, CLUB, SPADE
        Card *next;

    public:
        //CONSTRUCTORS/DESTRUCTOR
        Card();
        Card(int val, string s, Card *n);
        ~Card();
        Card *copy();

        //SETTERS: VALUE, SUIT, SYMBOL, next
        void setVALUE(int val)  {VALUE = val;}
        void setSUIT(string s)  {SUIT = s;}
        void setNext(Card *n)   {next = n;}

        //GETTERS: VALUE, SUIT, SYMBOL, next
        int getVALUE()          {return VALUE;}
        string getSUIT()        {return SUIT;}
        Card *getNext()         {return next;}

        void displayCard();
};

Card.cpp

#include "Card.h"
#include <iostream>
using namespace std;

Card::Card()
{
    VALUE = 0; SUIT = " "; next = NULL;
}

Card::Card(int val, string s, Card *n)
{
    VALUE = val; SUIT = s; next = n;
}

Card::~Card()
{
    if(next) free(next);
}

Card *Card::copy()
{
    Card *newCard = new Card(VALUE, SUIT, next);
    return newCard;
}

void Card::displayCard()
{
    cout << VALUE;
}

//tests whether two cards "match" -- comparison operator overload
bool operator == (Card &c1, Card &c2)
{
    return (c1.getVALUE() == c2.getVALUE() || c1.getSUIT() == c2.getSUIT());
}

Game.h

#pragma once
#include "Deck.h"

class Game
{
    protected:
        Deck *drawPile, *discardPile, *myHand, *compHand;
    public:
        Game();
};

Game.cpp

#include "Game.h"
#include "Deck.h"

Game::Game()
{
    drawPile = NULL; myHand = NULL; compHand = NULL; discardPile = NULL;

    drawPile->fill();
    for (int i = 0; i < 7; i++){
        myHand->drawCard();
        compHand->drawCard();
    }//end for
    discardPile->drawCard();
}

的main.cpp

#include "Game.h"
#include <iostream>
using namespace std;

void main()
{
    Game crazyEights;

    system("PAUSE");
}

1 个答案:

答案 0 :(得分:1)

下面:

Game::Game()
{
  drawPile = NULL;

  drawPile->fill();
  ...
}

指针drawPile的值为NULL,但是您告诉它指向的Deck(它不存在)来执行操作。这是取消引用空指针,它会导致未定义的行为

旁注:能够准备minimal complete example这样的错误非常重要;它会帮助您隔离问题,以便您自己找到它,或者有一个更简单的程序供我们查看。