"Card Deck"

Alright so this program is supposed to list out the 4 suits and all the cards in them and then give you a hand of 5 random cards but I'm getting this error,

First-chance exception at 0x00f541e6 in CardDeck.exe: 0xC0000005: Access violation reading location 0x00310028.
Unhandled exception at 0x00f541e6 in CardDeck.exe: 0xC0000005: Access violation reading location 0x00310028.

Here's the code,

Main.cpp:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
#include <iostream>
#include <cstdlib>
#include "Card.h"
#include "Deck.h"
using namespace std;

int main() {
	Card c1(SPADE, 2);
	Card c2(DIAMOND, 14);
	/*cout << "c1: " << c1.to_string() << endl;
	cout << "c2: " << c2.to_string() << endl;

	if (c1 < c2) {
		printf("c1 less than c2\n");
	} else {
		printf("c2 not less than c2\n");
	}*/

	Deck deck;
    deck.show();
    deck.shuffle();
    deck.show();
    Card *hand[5];
    deck.deal(hand, 5);
    printf("HAND BEFORE SORTING\n");
    for (int i=0; i<5; i++) {
        hand[i]->show(); printf(" ");
    }
    printf("\n");

    qsort(&hand, 5, sizeof(Card*), Card::compareCard);

    printf("HAND AFTER SORTING\n");
    for (int i=0; i<5; i++) {
        hand[i]->show(); printf(" ");
    }
    printf("\n");

    system("pause");
    return 0;
}

Card.cpp:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
#include "Card.h"

Card::Card(Suit suit, int value) {
	if (suit < SPADE || suit > CLUB) {
		throw new invalid_argument("Suit cannot be null.");			
	}
	if (value < 2 || value > 14) {
		throw new invalid_argument("Card value is out of range.");
	}
	this->suit = suit;
	this->value = value;
}

Suit Card::getSuit() {
	return suit;
}

int Card::getValue() {
	return value;
}

void Card::show() {
	printf("%s", to_string());
}

string Card::to_string() {
	string sCard;
	// TODO: return a string representation for a card, e.g. TWO:CLUB for the 2 of clubs.
	return sCard;
}

bool Card::operator<(const Card& c2){
    return value < c2.value;
}

int Card::compareCard(const void *c1, const void *c2) {
	//int value1 = ((Card *)c1)->value;
	//int value2 = ((Card *)c2)->value;
	Card *p1 = *(Card **)c1;
	Card *p2 = *(Card **)c2;
	int value1 = p1->value;
	int value2 = p2->value;
	return value1 - value2;
}

Card.h:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#ifndef CARD_H
#define CARD_H

#include "Suit.h"
#include <string>
using namespace std;

class Card 
{

private:
	Suit suit;
	int value;
public:
	Card(Suit suit, int value);
	Suit getSuit();
	int getValue();
	void show();
	string to_string();
	bool Card::operator<(const Card &c2);
	static int Card::compareCard(const void *c1, const void *c2);
};
#endif 

Suit.h:

1
2
3
4
#ifndef SUIT_H
#define SUIT_H
enum Suit {SPADE, HEART, DIAMOND, CLUB};
#endif 

Deck.cpp:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
#include "Deck.h"
#include <cstdlib>
#include <ctime>
using namespace std;


Deck::Deck() {
	printf("Deck() called\n");
	int startPosition = 0;
	//TODO: Create the CLUB cards
	createSuit(CLUB, startPosition);
	startPosition = startPosition + 13;
	//TODO: Create the HEART cards
	createSuit(HEART, 0);
	startPosition = startPosition + 13;
	//TODO: Create the DIAMOND cards
	createSuit(DIAMOND, 0);
	startPosition = startPosition + 13;
	//TODO: Create the SPADE cards
	createSuit(SPADE, 0);
	startPosition = startPosition + 13;
	topCard = 0;
}

Deck::~Deck() {
	printf("~Deck() called\n");
	//TODO: deallocate the cards of the deck
	for (int i=0; i<52; i++){
		delete cards[i];
	}
	//delete cards;
}


void Deck::createSuit(Suit s, int startPosition) {
	for (int i=2; i < 15; i++) {
		cards[startPosition++] = new Card(s, i);
	}
}

void Deck::shuffle() {
	srand(time(0));
	topCard = 0;
	int random;
	Card *temp;
	for (int i=0; i < 52; i++) {
		random = rand() % 52;
		temp = cards[i];
		cards[i] = cards[random];
		cards[random] = temp;
	}
}

void Deck::deal(Card *aDeal[], int count) {
	if (topCard+count > 52) {
		throw new invalid_argument("Deck is empty - cannot deal.");			
	}
	for (int i=0; i<count; i++) {
		aDeal[i] = cards[topCard+i];
	}
	topCard = topCard + count;
}

Card* Deck::getCard(int index) {
	if (index<0 || index>51) {
		throw new invalid_argument("Index out of range - cannot getCard.");
	}
	return this->cards[index];
}

void Deck::show() {
	//TODO: Show all of the cards in the deck
		printf("Deck: ");
	for (int i = 0; i < 4; i++) {
		for (int j = 0; j < 13; i++){
			(cards[i*13+j])->show();
			printf(" ");
			//*(cards[i*13+j]).show();
		}
		printf("\n      ");

	}
}

Deck.h:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#pragma once
#include "Card.h"

class Deck
{
private:
	Card *cards[52];
	int topCard;
	void createSuit(Suit s, int startPosition);

public:
	Deck();
	~Deck();
	void shuffle();
	void deal(Card *aDeal[], int count);
	Card *getCard(int index);
	void show();
};


Can anybody explain where I'm going wrong or what mistake I've made? It's just outputing

Deck() called
Deck:

And then a random strong of characters which I'm assuming is a memory address.


Last edited on
This shouldn't even compile.
Nevertheless:
1) In Deck::show():
1
2
3
4
    for (int i = 0; i < 4; i++)
    {
        for (int j = 0; j < 13; i++)
        {

Infinite loop here.

2) In main(): qsort(&hand, 5, sizeof(Card*), Card::compareCard);
hand is already passed as a pointe. Why you insist on passing pointer to pointer? It should be qsort(hand, 5, sizeof(Card*), Card::compareCard);. And why are you using old C sorting function instead of std::sort()?

3) In Card::show():
printf("%s", to_string());. You are using old C function. std::string type didn't exist then and printf() cannot output it. Use to_string().c_str() at least.
( http://cplusplus.com/articles/jEywvCM9/ )

The problem is in your Deck::deal function, where you set the values of aDeal.
aDeal is an array of pointers to Card instances. But those pointers don't point to anything yet. So trying to set their values will result in the exceptions you listed.
Also Deck constructor isn't working (fills cards array with garbage pointers now)
Topic archived. No new replies allowed.