【发布时间】:2026-01-25 08:45:01
【问题描述】:
所以,我正在尝试使用链接列表为一个班级创建一副牌,但我很难弄清楚为什么会出现错误:访问冲突读取位置 0x00000020。我对编码和动态分配还很陌生,我确信这是一个简单的解决方法,但我终其一生都无法弄清楚。我的 Deck 类是链表,我的 Card 类是节点。最终目标是让游戏成为 Crazy Eights。 Game 类应该有四个牌组(抽牌堆、弃牌堆、我的手、电脑手)。
代码在deck.cpp 中的addCard() 函数中的SIZE++; 中断
甲板.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
卡.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();
};
卡片.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());
}
游戏.h
#pragma once
#include "Deck.h"
class Game
{
protected:
Deck *drawPile, *discardPile, *myHand, *compHand;
public:
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");
}
【问题讨论】:
-
Decks 必须是指针吗?引用,实际对象不是替代品吗?如果你必须使用指针,智能指针会让你头疼。 -
我不确定甲板是否应该是指针。
-
不要让它们成为指针......
-
我觉得自己太笨了...我花了好几个小时看这个,这就是问题所在...
标签: c++ linked-list dynamic-allocation