2

So I am trying to create a simple poker game to re familiarize myself with C++, as I have been out of it for a while and would like to get back into C++.

I am having issues with a stack (appropriate, no?), from the STL. I can't seem to get it to allow me to add anything to the stack. Every time I call the push function on the stack object, it throws a memory access violation... I even tried creating a stack of integers, and adding those to the stack, but it still throws the memory access violation error. Which is weird.

The code that currently adds the object to the stack is:

//shuffles the deck
void Deck::shuffle()
{
    int index;

    for(int i = 0; i < DECK_SIZE; i++)
    {
        index = (rand() % 52);

        if(deck[index].drawn == false)
        {
            shuffledDeck.push(deck[index]); //throws the error
            deck[index].drawn = true;
        }
        else
        {
            i--;
        }
    }
}

I set a break point, and followed it down the rabbit hole, and found out it throws the exception here:

void push_back(const value_type& _Val)
{   // insert element at end
    this->_Orphan_all();
    _PUSH_BACK_BEGIN;            //EXCEPTION!
    this->_Getal().construct(
    this->_Map[_Block] + _Newoff % _DEQUESIZ, _Val);
    _PUSH_BACK_END;
}

Which is located deque.cpp... Which is odd.

For reference, here is the rest of the code I think may be necessary:

Deck.cpp

#include "stdafx.h"
#include "Deck.h"
#include <time.h>

using namespace std;
using namespace CardDeck;

const int DECK_SIZE = 52;



CARD deck[DECK_SIZE];
std::stack<CARD> shuffledDeck;



Deck::Deck()
{
    srand((unsigned int)time(NULL));
    loadCards();
}

Deck::~Deck()
{
}

//Draws a card from the deck
CARD Deck::drawCard()
{
    CARD card = shuffledDeck.front();
    shuffledDeck.pop();
    return card;
}

//shuffles the deck
void Deck::shuffle()
{
    int index;

    for(int i = 0; i < DECK_SIZE; i++)
    {
        index = (rand() % 52);

        if(deck[index].drawn == false)
        {
            shuffledDeck.push(deck[index]);
            deck[index].drawn = true;
        }
        else
        {
            i--;
        }
    }
}

    void Deck::loadCards()
    {

        //create input file stream
        ifstream cardList;

        //open the list of cards
        cardList.open("card.txt", ios::in);

        //if the file has opened successfully
        if(cardList.is_open())
        {
            int index = 0;

            //and while the cardlist has data left
            while(cardList.good())
            {
                char * context = NULL;
                CARD card = CARD();
                //read the cards
                string line;
                getline(cardList, line);

                char * s = strtok_s(&line[0], ", ", &context);

                card.value = *s;

                s = strtok_s(NULL, ", ", &context);

                card.suit = s;
                card.drawn = false;

                deck[index] = card;

                index++;
            }
        }

    }

Deck.h (contains the CARD struct)

#pragma once
#include <string>
#include <stack>
#include <fstream>
#include <sstream>
#include <iostream>
#include <string>

namespace CardDeck
{
    struct CARD
    {
        public:
            std::string suit;
            char value;
            bool drawn;

            CARD(){}

            CARD(const CARD& card)
            {
                suit = card.suit;
                value = card.value;
                drawn = card.drawn;
            }

            CARD& operator= (const CARD& card)
            {
                suit = card.suit;
                value = card.value;
                drawn = card.drawn;

                return *this;
            }
    };

        class Deck
        {
            public:
                Deck();
                ~Deck();
                Deck(const Deck& deck);
                CARD drawCard();
                void shuffle();

            private:
                void loadCards();

        };
    }
jbenscoter
  • 171
  • 1
  • 2
  • 11
  • 1
    Instead of doing a manual shuffle, there is a standard function for that: [`std::random_shuffle`](http://en.cppreference.com/w/cpp/algorithm/random_shuffle). – Some programmer dude Nov 20 '12 at 01:57
  • Oh gawd, I tried changing it to a queue and forgot to change it back haha. But there error happens with the queue too... my bad! I have updated it to say stack... – jbenscoter Nov 20 '12 at 01:57
  • 1
    It looks like your `Deck` class has instance methods that modify the global (file-scoped) variables `deck` and `shuffledDeck`. Are you sure that's what you want? It seems like those variables should actually be member variables, inside your `Deck` class. – ruakh Nov 20 '12 at 02:00
  • nice catch, that is not what I want. – jbenscoter Nov 20 '12 at 02:02
  • 1
    minor style issue, possibly you missed this but prefer `index = (rand() % DECK_SIZE);` to `index = (rand() % 52);` since you already have the variable ready – Karthik T Nov 20 '12 at 02:02
  • Can you please post card.txt as well, or maybe a link to pastebin with it? I would like to try the whole program. – vidit Nov 20 '12 at 02:03
  • I change them to member variables and now I am getting an access write violation... – jbenscoter Nov 20 '12 at 02:04
  • @vidit will do that. One sec... – jbenscoter Nov 20 '12 at 02:05
  • Link to card.txt... it's quite simple http://pastebin.com/92wVpNkx – jbenscoter Nov 20 '12 at 02:06

1 Answers1

4

You're probably writing past the end of the deck array in loadCards(), corrupting memory.

Even if you have exactly 52 lines of data, cardlist.good() will return true until after an EOF indication.

You might want to try the following loop instead (untested):

string line;
while(getline(cardList, line) && (index < 52))
{
    char * context = NULL;
    CARD card = CARD();

    char * s = strtok_s(&line[0], ", ", &context);

    card.value = *s;

    s = strtok_s(NULL, ", ", &context);

    card.suit = s;
    card.drawn = false;

    deck[index] = card;

    index++;
}
Michael Burr
  • 333,147
  • 50
  • 533
  • 760
  • Wow, good call, I never would've checked because the exception is thrown when I tried to push onto the stack, but this was exactly it... Do you have any idea why it would do that? Thank you! – jbenscoter Nov 20 '12 at 02:10
  • 2
    You're corrupting the `shuffledDeck` object when you write past the end of the array. That doesn't get noticed until the object is used and the bogus object state causes the crash. – Michael Burr Nov 20 '12 at 02:16
  • The `EOF` problem is a common anti-pattern in C/C++ (and other languages?): http://stackoverflow.com/questions/5431941 and http://www.drpaulcarter.com/cs/common-c-errors.php#4.2 – Michael Burr Nov 20 '12 at 02:22