Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

"Program received signal SIGSEGV, Segmentation fault. In ?? () ()" when debugging my C++ project in Code::Blocks

Tags:

c++

codeblocks

first post here. I'm doing a university assignment where I'm required to finish implementing a program that simulates the opening bid of a game of contract bridge. I was provided with the following file that contains the main function:

/// File: bridge.cpp
/// Creates a deck of cards, shuffles them and displays them.

#include <iostream>
#include <iomanip>
#include <fstream>
#include "game.h"

const int NUM_DEALS = 4;

using namespace std;

int main(int argc, char *argv[]) {

   Game game;
   ifstream infile;
   bool fromFile = false;

   if (argc == 2) {

      // open the file and check it exists
      infile.open(argv[1]);
      if (infile.fail()) {
         cerr <<  "Error: Could not find file" << endl;
         return 1;
      }
      fromFile = true;
   }

   for (int deal = 0; deal < NUM_DEALS; deal++) {
      game.setup(fromFile);
      if (fromFile) {
         infile >> game;
      }
      game.deal();
      game.auction();
      cout << game << endl;
      cout << endl << "=============================================================="    << endl << endl;
      game.nextDealer();
   }

   // close the file
   if (argc == 2) {
      infile.close();
   }

   return 0;
}

I've completed the other classes that simulate the card objects, the deck object, the hand objects and the game object but my program crashed when I clicked "Build and Run". The next logical step was to debug, but when I did so I got the following output in the debugger window:

Building to ensure sources are up-to-date
Selecting target: 
Release
Adding source dir: C:\Users\Jack\Documents\CodeBlocks\BridgeAssignment\
Adding source dir: C:\Users\Jack\Documents\CodeBlocks\BridgeAssignment\
Adding file: C:\Users\Jack\Documents\CodeBlocks\BridgeAssignment\bin\Release\BridgeAssignment.exe
Changing directory to: C:/Users/Jack/Documents/CodeBlocks/BridgeAssignment/.
Set variable: PATH=.;C:\Program Files (x86)\CodeBlocks\MinGW\bin;C:\Program Files (x86)\CodeBlocks\MinGW;C:\Program Files (x86)\PHP;C:\Program Files\Common Files\Microsoft Shared\Windows Live;C:\Program Files (x86)\Common Files\Microsoft Shared\Windows Live;C:\Program Files (x86)\Intel\iCLS Client;C:\Program Files\Intel\iCLS Client;C:\Program Files (x86)\AMD APP\bin\x86_64;C:\Program Files (x86)\AMD APP\bin\x86;C:\Windows\System32;C:\Windows;C:\Windows\System32\wbem;C:\Windows\System32\WindowsPowerShell\v1.0;C:\Program Files (x86)\ATI Technologies\ATI.ACE\Core-Static;C:\Program Files\Intel\Intel(R) Management Engine Components\DAL;C:\Program Files\Intel\Intel(R) Management Engine Components\IPT;C:\Program Files (x86)\Intel\Intel(R) Management Engine Components\DAL;C:\Program Files (x86)\Intel\Intel(R) Management Engine Components\IPT;C:\Program Files\Sony\VAIO Improvement;C:\Program Files (x86)\Sony\VAIO Startup Setting Tool;C:\Program Files (x86)\Windows Live\Shared;C:\Program Files (x86)\Jahshaka\..\gtk2\bin;C:\Program Files (x86)\Jahshaka\..\mlt\bin;C:\Program Files (x86)\OpenLibraries\bin;C:\Users\Jack\AppData\Local\Smartbar\Application;C:\Program Files\Microsoft\Web Platform Installer;C:\Program Files (x86)\Microsoft ASP.NET\ASP.NET Web Pages\v1.0;C:\Program Files (x86)\Windows Kits\8.0\Windows Performance Toolkit;C:\Program Files\Microsoft SQL Server\110\Tools\Binn;C:\Program Files (x86)\QuickTime\QTSystem;C:\Program Files (x86)\Autodesk\Backburner
Starting debugger: C:\Program Files (x86)\CodeBlocks\MINGW\bin\gdb.exe -nx -fullname  -quiet  -args C:/Users/Jack/Documents/CodeBlocks/BridgeAssignment/bin/Release/BridgeAssignment.exe
done
Registered new type: wxString
Registered new type: STL String
Registered new type: STL Vector
Setting breakpoints
Reading symbols from C:\Users\Jack\Documents\CodeBlocks\BridgeAssignment\bin\Release\BridgeAssignment.exe...(no debugging symbols found)...done.
Debugger name and version: GNU gdb (GDB) 7.5
Child process PID: 13628
Program received signal SIGSEGV, Segmentation fault.
In ?? () ()

If it would help in solving the problem, here are my other classes.

Card.h:

#include <string>
#include <iostream>
#ifndef CARD_H
#define CARD_H

using namespace std;

enum Suit {CLUBS, DIAMONDS, HEARTS, SPADES};

enum Rank {TWO, THREE, FOUR, FIVE, SIX, SEVEN, EIGHT, NINE, TEN, JACK, QUEEN, KING, ACE};

class Card
{
    public:
        Card();

        Card(Rank rank, Suit suit);

        Card(string);

        ~Card();

        Rank getRank();

        Suit getSuit();

        bool operator() (Card*, Card*);

        friend ostream& operator<<(ostream&, Card&);

    private:
        Suit suit;

        Rank rank;
};

#endif // CARD_H

Card.cpp:

#include "card.h"
#include <iostream>

Card::Card()
{
    this->suit = CLUBS;
    this->rank = TWO;
}

Card::Card(Rank rank, Suit suit)
{
    this->suit = suit;
    this->rank = rank;
}

Card::Card(string str)
{
    char rank = str.at(0);
    char suit = str.at(1);
    Rank cardRank = TWO;
    Suit cardSuit = CLUBS;
    switch(rank)
    {
        case '2': cardRank = TWO;
            break;
        case '3': cardRank = THREE;
            break;
        case '4': cardRank = FOUR;
            break;
        case '5': cardRank = FIVE;
            break;
        case '6': cardRank = SIX;
            break;
        case '7': cardRank = SEVEN;
            break;
        case '8': cardRank = EIGHT;
            break;
        case '9': cardRank = NINE;
            break;
        case 'T': cardRank = TEN;
            break;
        case 'J': cardRank = JACK;
            break;
        case 'Q': cardRank = QUEEN;
            break;
        case 'K': cardRank = KING;
            break;
        case 'A': cardRank = ACE;
            break;
    }
    switch(suit)
    {
        case 'C': cardSuit = CLUBS;
            break;
        case 'D': cardSuit = DIAMONDS;
            break;
        case 'H': cardSuit = HEARTS;
            break;
        case 'S': cardSuit = SPADES;
            break;
    }
    this->suit = cardSuit;
    this->rank = cardRank;
}

Card::~Card()
{

}

Rank Card::getRank()
{
    return this->rank;
}

Suit Card::getSuit()
{
    return this->suit;
}

bool Card::operator() (Card* cardOne, Card* cardTwo)
{
    if (cardOne->getSuit() > cardTwo->getSuit())
    {
        return cardOne->getRank() >= cardTwo->getRank();
    }
    else if (cardOne->getSuit() < cardTwo->getSuit())
    {
        return cardOne->getRank() > cardTwo->getRank();
    }
    else
    {
        return cardOne->getRank() > cardTwo->getRank();
    }
}

ostream& operator <<(ostream& out, Card& card)
{
    string cardID = "";
    switch(card.getRank())
    {
        case TWO: cardID += "2";
            break;
        case THREE: cardID += "3";
            break;
        case FOUR: cardID += "4";
            break;
        case FIVE: cardID += "5";
            break;
        case SIX: cardID += "6";
            break;
        case SEVEN: cardID += "7";
            break;
        case EIGHT: cardID += "8";
            break;
        case NINE: cardID += "9";
            break;
        case TEN: cardID += "T";
            break;
        case JACK: cardID += "J";
            break;
        case QUEEN: cardID += "Q";
            break;
        case KING: cardID += "K";
            break;
        case ACE: cardID += "A";
    }
    switch(card.getSuit())
    {
        case CLUBS: cardID += "C";
            break;
        case DIAMONDS: cardID += "D";
            break;
        case HEARTS: cardID += "H";
            break;
        case SPADES: cardID += "S";
            break;
    }
    out << cardID;
    return out;
}

Deck.h:

#ifndef DECK_H
#define DECK_H
#include "card.h"
#include <iostream>

using namespace std;

class Deck
{
    public:
        Deck();

        virtual ~Deck();

        void reset();

        Card* dealNextCard();

        void shuffle();

        friend ostream& operator<<(ostream&, Deck&);

        friend istream& operator>>(istream&, Deck&);

    private:
        int cardsDealt;
        Card** deckArray;

};

#endif // DECK_H

Deck.cpp:

#include "Deck.h"
#include "Card.h"
#include "random.h"
#include <iostream>

Deck::Deck()
{
    deckArray = new Card*[52];
    int counter = 0;
    cardsDealt = 0;
    for (int i = 0; i < 13; i++)
    {
        for (int j = 0; j < 4; j++)
        {
            *deckArray[counter] = Card((Rank)i, (Suit)j);
            counter++;
        }
    }
}

Deck::~Deck()
{
    //dtor
}

void Deck::reset()
{
    cardsDealt = 0;
}

Card* Deck::dealNextCard()
{
    cardsDealt++;
    return deckArray[cardsDealt-1];
}

void Deck::shuffle()
{
    Random rand;
    int index1 = rand.randomInteger(0,53);
    int index2 = rand.randomInteger(0,53);
    Card temp = *deckArray[index1];
    deckArray[index1] = deckArray[index2];
    *deckArray[index2] = temp;
}

ostream& operator<<(ostream& out, Deck& deck)
{
    string cards = "";
    for (int i = 0; i < 52; i++)
    {
        out << " " << deck.deckArray[i];
    }
    return out;
}

istream& operator>>(istream& in, Deck& deck)
{
    string text[52];
    for (int i = 0; i < 52; i++)
    {
        in >> text[i];
    }
    for (int i = 0; i < 52; i++)
    {
        char rank = text[i].at(0);
        char suit = text[i].at(1);
        Rank cardRank = TWO;
        Suit cardSuit = CLUBS;
        switch(rank)
        {
            case '2': cardRank = TWO;
                break;
            case '3': cardRank = THREE;
                break;
            case '4': cardRank = FOUR;
                break;
            case '5': cardRank = FIVE;
                break;
            case '6': cardRank = SIX;
                break;
            case '7': cardRank = SEVEN;
                break;
            case '8': cardRank = EIGHT;
                break;
            case '9': cardRank = NINE;
                break;
            case 'T': cardRank = TEN;
                break;
            case 'J': cardRank = JACK;
                break;
            case 'Q': cardRank = QUEEN;
                break;
            case 'K': cardRank = KING;
                break;
            case 'A': cardRank = ACE;
                break;
        }
        switch(suit)
        {
            case 'C': cardSuit = CLUBS;
                break;
            case 'D': cardSuit = DIAMONDS;
                break;
            case 'H': cardSuit = HEARTS;
                break;
            case 'S': cardSuit = SPADES;
                break;
        }
        *deck.deckArray[i] = Card(cardRank, cardSuit);
    }
    return in;
}

Hand.h:

#ifndef HAND_H
#define HAND_H
#include "card.h"
#include <iostream>
#include <vector>
#include <set>

class Hand
{
    public:
        Hand();

        virtual ~Hand();

        void clear();

        void addCard(Card*);

        string makeBid();

        friend ostream& operator<< (ostream&, Hand&);

    private:
        unsigned int strength;

        unsigned int highCardPoints;

        unsigned int lengthPoints;

        int addHighCards(vector<Card*>);

        int findLengthPoints(vector<Card*>);

        void getStrength();

        bool balanced;

        void getBalance();

        void getWinningSuit();

        set<int> suitLen;

        vector<Card*> clubs;

        vector<Card*> diamonds;

        vector<Card*> hearts;

        vector<Card*> spades;

        vector< vector<Card*> > winningSuit;

        vector<string> winningSuitStr;
};
#endif // HAND_H

Hand.cpp:

#include "Hand.h"
#include "card.h"
#include <vector>
#include <set>
#include <iterator>
#include <iostream>

Hand::Hand()
{
    strength = 0;
    balanced = false;
}

Hand::~Hand()
{
    //dtor
}

void Hand::clear()
{
    clubs.clear();
    diamonds.clear();
    hearts.clear();
    spades.clear();
    strength = 0;
    balanced = false;
}

void Hand::addCard(Card* card)
{
    switch(card->getSuit())
    {
        case CLUBS: clubs.push_back(card);
            break;
        case DIAMONDS: diamonds.push_back(card);
            break;
        case HEARTS: hearts.push_back(card);
            break;
        case SPADES: spades.push_back(card);
            break;
    }
}

void Hand::getBalance()
{
    if ((suitLen.count(4)==2 && suitLen.count(3)==1 && suitLen.count(2)==1)
        || (suitLen.count(4)==1 && suitLen.count(3)==3))
        {
            balanced = true;
        }
        else
        {
            balanced = false;
        }
}

void Hand::getWinningSuit()
{
    if (clubs.size() >= diamonds.size() && clubs.size() >= hearts.size() && clubs.size() >= spades.size())
    {
        winningSuit.push_back(clubs);
        winningSuitStr.push_back("C");
    }
    if (diamonds.size() >= clubs.size() && diamonds.size() >= hearts.size() && diamonds.size() >= spades.size())
    {
        winningSuit.push_back(diamonds);
        winningSuitStr.push_back("D");
    }
    if (hearts.size() >= clubs.size() && hearts.size() >= diamonds.size() && hearts.size() >= spades.size())
    {
        winningSuit.push_back(hearts);
        winningSuitStr.push_back("H");
    }
    if (spades.size() >= clubs.size() && spades.size() >= diamonds.size() && spades.size() >= hearts.size())
    {
        winningSuit.push_back(spades);
        winningSuitStr.push_back("S");
    }
}

int Hand::addHighCards(vector<Card*> suit)
{
    int highCardPoints = 0;
    for (unsigned int i = 0; i < suit.size(); i++)
    {
        switch(suit[i]->getRank())
        {
            case ACE: highCardPoints += 4;
                break;
            case KING: highCardPoints += 3;
                break;
            case QUEEN: highCardPoints += 2;
                break;
            case JACK: highCardPoints += 1;
                break;
            default:
                break;
        }
    }
    return highCardPoints;
}

int Hand::findLengthPoints(vector<Card*> suit)
{
    if (suit.size() > 4)
    {
        return suit.size() - 4;
    }
    return 0;
}

void Hand::getStrength()
{
    highCardPoints = 0;
    lengthPoints = 0;
    highCardPoints += addHighCards(clubs);
    highCardPoints += addHighCards(diamonds);
    highCardPoints += addHighCards(hearts);
    highCardPoints += addHighCards(spades);
    lengthPoints += findLengthPoints(clubs);
    lengthPoints += findLengthPoints(diamonds);
    lengthPoints += findLengthPoints(hearts);
    lengthPoints += findLengthPoints(spades);
    strength = highCardPoints + lengthPoints;
}

string Hand::makeBid()
{
    suitLen.insert(clubs.size());
    suitLen.insert(diamonds.size());
    suitLen.insert(hearts.size());
    suitLen.insert(spades.size());
    getStrength();
    getBalance();
    getWinningSuit();
    if (balanced)
    {
        if (strength >= 0 && strength <= 12)
        {
            if (suitLen.count(6)==1)
            {
                if (winningSuit[0]==clubs)
                {
                    return "PASS";
                }
                else
                {
                    return "2" + winningSuitStr[0];
                }
            }
            else if (suitLen.count(6)==2)
            {
               return "2" + winningSuitStr[0];
            }
            else if (suitLen.count(7)==1)
            {
                return "3" + winningSuitStr[0];
            }
            else if (suitLen.count(8)==1)
            {
                return "4" + winningSuitStr[0];
            }
            else
            {
                return "PASS";
            }
        }
        else if (strength >= 13 && strength <= 21)
        {
            if (winningSuit.size()==2 && winningSuit[0].size()>=5)
            {
                return "1" + winningSuitStr[0];
            }
            else if (winningSuit.size()>=2 && winningSuit[0].size()==4)
            {
                return "1" + winningSuitStr[winningSuitStr.size()-1];
            }
            else
            {
                return "1" + winningSuitStr[0];
            }
        }
        else /**< if (strength >= 22)*/
        {
            return "2C";
        }
    }
    else
    {
        if (strength >= 0 && strength <= 12)
        {
            return "PASS";
        }
        else if (strength == 13 || strength == 14 || strength == 18 || strength == 19)
        {
            if (clubs.size() == diamonds.size())
            {
                if (clubs.size() == 4)
                {
                    return "1D";
                }
                return "1C";
            }
            else
            {
                if (clubs.size() > diamonds.size())
                {
                    return "1C";
                }
                return "1D";
            }
        }
        else if (strength >= 15 && strength <= 17)
        {
            return "1 NT";
        }
        else if (strength == 20 || strength == 21)
        {
            return "2 NT";
        }
        else
        {
            return "2C";
        }
    }
}

ostream& operator<<(ostream& out, Hand& hand)
{
    out << "SPADES : ";
    for (unsigned int i = 0; i < hand.spades.size(); i++)
    {
        out << hand.spades[i] << " ";
    }
    out << endl;
    out << "HEARTS : ";
    for (unsigned int i = 0; i < hand.hearts.size(); i++)
    {
        out << hand.hearts[i] << " ";
    }
    out << endl;
    out << "DIAMONDS : ";
    for (unsigned int i = 0; i < hand.diamonds.size(); i++)
    {
        out << hand.diamonds[i] << " ";
    }
    out << endl;
    out << "CLUBS : ";
    for (unsigned int i = 0; i < hand.clubs.size(); i++)
    {
        out << hand.clubs[i] << " ";
    }
    out << endl;
    out << hand.highCardPoints << " HCP, " << hand.lengthPoints << " LP, Total = " << hand.strength << endl;
    return out;
}

Game.h:

#ifndef GAME_H
#define GAME_H
#include <iostream>
#include "Deck.h"
#include "Hand.h"

enum Position {NORTH, EAST, SOUTH, WEST};

class Game
{
    public:
        Game();

        virtual ~Game();

        void setup(bool);

        void deal();

        void auction();

        void nextDealer();

        friend ostream& operator<< (ostream&, Game&);

        friend istream& operator>> (istream&, Game&);

    private:
        Deck gameDeck;

        Hand** gameHands;

        Position dealer;

        string* openingBid;

};

#endif // GAME_H

Game.cpp:

#include "Game.h"
#include "Deck.h"
#include "Hand.h"
#include <iostream>

Game::Game()
{
    gameDeck = Deck();
    gameHands = new Hand*[4];
    gameHands[0] = new Hand();
    gameHands[1] = new Hand();
    gameHands[2] = new Hand();
    gameHands[3] = new Hand();
    dealer = NORTH;
}

Game::~Game()
{
    //dtor
}

void Game::setup(bool fromFile)
{
    if (!fromFile)
    {
        gameDeck.shuffle();
        gameDeck.reset();
        for (unsigned int i = 0; i < 4; i++)
        {
            gameHands[i]->clear();
        }
    }
}

void Game::deal()
{
    for (unsigned int i = 0; i < 52; i++)
    {
        gameHands[(i%4)+1]->addCard(gameDeck.dealNextCard());
    }
}

void Game::auction()
{
    openingBid = new string[2];
    openingBid[0] = "PASS";
    openingBid[1] = "PASS";
    for (unsigned int i = 0; i < 4; i++)
    {
        if (gameHands[i]->makeBid() != "PASS")
        {
            switch(i)
            {
                case 0: openingBid[0] = "NORTH";
                    break;
                case 1: openingBid[0] = "EAST";
                    break;
                case 2: openingBid[0] = "SOUTH";
                    break;
                case 3: openingBid[0] = "WEST";
                    break;
            }
            openingBid[1] = gameHands[i]->makeBid();
            break;
        }
    }
}

void Game::nextDealer()
{
    int temp = (int)dealer;
    temp++;
    temp = temp % 4;
    dealer = (Position)temp;
}

ostream& operator<< (ostream& out, Game& game)
{
    out << "NORTH";
    out << game.gameHands[0];
    out << endl;
    out << "EAST";
    out << game.gameHands[1];
    out << endl;
    out << "SOUTH";
    out << game.gameHands[2];
    out << endl;
    out << "WEST";
    out << game.gameHands[3];
    out << endl;
    return out;
}

istream& operator>> (istream& in, Game& game)
{
    in >> game.gameDeck;
    return in;
}

Also here is the premade random class I'm using.

Random.h:

#ifndef _random_h
#define _random_h


/// This class provides several functions for generating pseud-random numbers.
///
class Random {
public:

   /// \brief
   ///
   /// Initialize the randomizer.
   ///
   Random();


   /// \brief
   ///
   /// Generates a random integer number greater than or equal to low and less than high.
   /// \param low int - lower bound for range (inclusive).
   /// \param high int - upper bound for range (exclusive).
   /// \return int - A random integer number greater than or equal to low and less than high.
   ///
   int randomInteger(int low, int high);

   /// \brief
   /// Generates a random real number greater than or equal to low and less than high.
   ///
   /// \param low double - lower bound for range (inclusive).
   /// \param high double - upper bound for range (exclusive).
   /// \return double - A random real number greater than or equal to low and less than high.
   ///
   double randomReal(double low, double high);

   /// \brief
   /// Generates a true false outcome based on the probability p.
   /// Calling randomChance(0.30) returns true 30% of the time.
   ///
   /// \param p double - Value between 0 (never) and 1 (always).
   /// \return bool - true or false based on p.
   ///
   bool randomChance(double p);

private:

   /// \brief
   ///
   /// Initializes teh random-number generator so that its results are unpredictable.  If this function is
   /// not called the other functions will return the same values on each run.
   ///
   void randomize();
};

#endif // _random_h

Random.cpp:

#include <cstdlib>
#include <ctime>
#include "random.h"

/// This class provides several functions for generating pseud-random numbers.
///
Random::Random() {
   randomize();
}


/// \brief
/// Generates a random integer number greater than or equal to low and less than or equal to high.
///
/// \param low int - lower bound for range (inclusive).
/// \param high int - upper bound for range (inclusive).
/// \return int - A random integer number greater than or equal to low and less than or equal to high.
///
int Random::randomInteger(int low, int high) {
   double d = double(rand()) / (double(RAND_MAX) + 1);
   int k = int(d * (high - low  + 1));
   return low + k;
}

/// \brief
/// Generates a random real number greater than or equal to low and less than high.
///
/// \param low double - lower bound for range (inclusive).
/// \param high double - upper bound for range (exclusive).
/// \return double - A random real number greater than or equal to low and less than high.
///
double Random::randomReal(double low, double high) {
   double d = double(rand()) / (double(RAND_MAX) + 1);
   return low + d * (high - low);
}

/// \brief
/// Generates a true false outcome based on the probability p.
/// Calling randomChance(0.30) returns true 30% of the time.
///
/// \param p double - Value between 0 (never) and 1 (always).
/// \return bool - true or false based on p.
///
bool Random::randomChance(double p) {
   return randomReal(0, 1) < p;
}

/// \brief
///
/// Initializes the random-number generator so that its results are unpredictable.  If this function is
/// not called the other functions will return the same values on each run.
///
void Random::randomize() {
   srand(int(time(NULL)));
}

I've been hunting around the internet for solutions to this problem, but nothing seemed to fit my scenario, with the crash on run and the SIGSEGV on debug. Hoping someone here can help me, I'm getting desperate lol.

Thanks.

like image 715
boyde712 Avatar asked Apr 16 '14 11:04

boyde712


People also ask

How do you overcome SIGSEGV?

Don't use pointers. And if you do always check for NULL pointers. Minimize the use of pointers, access any kind of arrays within its bounds, check whether pointer is NULL before using, make sure you allocate new memory before using a pointer which you have already freed (it may not be giving NULL ).

What does it mean when a program receives a SIGSEGV?

The SIGSEGV signal is raised when you attempt to illegally access or modify memory. SIGSEGV is usually caused by using uninitialized or NULL pointer values or by memory overlays. By default, SIGSEGV causes program termination with an appropriate ABEND code (0C4 for a protection error or 0C5 for an addressing error).

What is SIGSEGV in Linux?

In a nutshell, segmentation fault refers to errors due to a process's attempts to access memory regions that it shouldn't. When the kernel detects odd memory access behaviors, it terminates the process issuing a segmentation violation signal (SIGSEGV).


2 Answers

Your code is way too much to be sure but the problem resides very likely in yout deck constructor.

Deck::Deck()
{
  // Here you allocate space for 52 pointers, not Cards
  deckArray = new Card*[52];
  ...
    // at this location there's no space for a card but for a pointer
    //*deckArray[counter] = Card((Rank)i, (Suit)j);
    // so you should do this instead:
    deckArray[counter] = new Card((Rank)i, (Suit)j);
    // to allocate needed space for the card
  ...
}

To sum it up, you never allocate the space needed to store the cards.

like image 149
dogiordano Avatar answered Oct 22 '22 05:10

dogiordano


The deckArray in Deck is an array of pointers, but you never allocate its elements.

This means that all your assignments through these pointers are invalid dereferences whose behaviour is undefined.

You need to either allocate those elements with new, or avoid pointers, which is usually the best way.

Replacing Hand** gameHands; with Hand gameHands[4]; and Card** deckArray; with Card deckArray[52]; would be a good start.

(Unlike in java, where "new" is the only way to instantiate classes, C++ programmers usually only use that word when necessary.)

like image 2
molbdnilo Avatar answered Oct 22 '22 04:10

molbdnilo