Note that there are some explanatory texts on larger screens.

plurals
  1. POSegfault/ "Vector is not dereferencable" on std::vector push_back
    text
    copied!<p>I have some C++ code dealing with a card game and it's segfaulting and I can't figure out why. I tried running it in MSVS 2012 to get a more clear error and it threw a "Vector is not dereferencable." I tried doing some research but I'm lost on where the error is coming from. I'm guessing the bug isn't in the push_back but rather somewhere else as the problem line works most of the time. The error occurs in Table::hit(). After looking through the code I think the bug may possibly lie in Hand::split() but I am not sure and I am even less sure how to fix it. Thanks!</p> <pre><code>class Hand { public: std::vector&lt;Card&gt; hand; bool active, doubled, isBlackjack, busted; Hand() : active(true), doubled(false), isBlackjack(false), busted(false) { } Hand(const Hand&amp; _hand); void removeCard(Card card) { hand.erase( hand.begin() ); } Card split(); void clear(); int cards() const { return hand.size(); } int getHandValue() const; Card at(int pos) { return hand[pos]; } friend std::ostream&amp; operator&lt;&lt; (std::ostream&amp; out, const Hand&amp; hand); friend std::ostream&amp; operator&lt;&lt; (std::ostream&amp; out, const std::vector&lt;Hand&gt;&amp; hands); }; Hand::Hand(const Hand&amp; _hand) : hand(_hand.hand), active(_hand.active), doubled(_hand.doubled), isBlackjack(_hand.isBlackjack), busted(_hand.busted) { } Card Hand::split() { //COULD THE BELOW CODE BE CAUSING ISSUES? Card card = hand[0]; hand.erase( hand.begin() ); return card; } void Hand::clear() { active = true; hand.clear(); } int Hand::getHandValue() const { int value(0), aces(0); for(std::vector&lt;Card&gt;::const_iterator it = hand.cbegin(); it != hand.cend(); ++it) { value += getCardValue(it-&gt;getRank()); if(it-&gt;getRank() == ACE) ++aces; } while(aces &gt; 0 &amp;&amp; value &gt; 21) { value -= 10; --aces; } return value; } std::ostream&amp; operator&lt;&lt; (std::ostream&amp; out, const Hand&amp; hand) { for(std::vector&lt;Card&gt;::const_iterator it = hand.hand.begin(); it != hand.hand.end(); ++it) { out &lt;&lt; *it &lt;&lt; " "; } out &lt;&lt; hand.getHandValue(); return out; } std::ostream&amp; operator&lt;&lt; (std::ostream&amp; out, const std::vector&lt;Hand&gt;&amp; hands) { for(std::vector&lt;Hand&gt;::const_iterator it = hands.begin(); it != hands.end(); ++it) { out &lt;&lt; *it &lt;&lt; " "; } return out; } class Table { protected: Shoe shoe; Strategy strat; Hand dealer; std::vector&lt; Hand &gt; player; double balance, blackjackPayoff; bool hitSoft17; void deal(); void hit(int split=0); void split(int split=0); double stand(); Action getUserAction(); bool isCurrentGame(); public: Table(int decks, int _balance); double bet; void play(); void print(); void simulate(std::string fileName, int hands); }; Table::Table(int decks, int _balance) : shoe(decks), balance(_balance), blackjackPayoff(1.5), hitSoft17(true), bet(10) {} bool Table::isCurrentGame() { for(std::vector&lt;Hand&gt;::iterator it = player.begin(); it != player.end(); ++it) { if(it-&gt;active) return true; } return false; } void Table::deal() { dealer.clear(); player.clear(); dealer.addCard( shoe.pullCard(true) ); dealer.addCard( shoe.pullCard() ); player.push_back(Hand()); player[0].addCard( shoe.pullCard() ); player[0].addCard( shoe.pullCard() ); if(player[0].getHandValue() == 21 &amp;&amp; dealer.getHandValue() == 21) { player[0].active = false; } else if(player[0].getHandValue() == 21) { player[0].active = false; } else if(dealer.getHandValue() == 21) { player[0].active = false; } } void Table::hit(int split) { player[split].hand.push_back( shoe.pullCard() ); //SEGFAULT HERE if(player[split].getHandValue() &gt; 21) { player[split].active = false; } } void Table::split(int split) { player.push_back(Hand()); player[player.size() - 1].hand.push_back( player[split].split() ); player[split].hand.push_back( shoe.pullCard() ); player[player.size() - 1].hand.push_back( shoe.pullCard() ); if(player[split].getHandValue() == 21) { player[split].active = false; } else if(player[player.size() - 1].getHandValue() == 21) { player[player.size() - 1].active = false; } } double Table::stand() { double winnings(0.0); bool allNats(true); //dealer.push_back( shoe.pullCard() ); for(std::vector&lt;Hand&gt;::iterator it = player.begin(); it != player.end(); ++it) { if(it-&gt;cards() == 2 &amp;&amp; it-&gt;getHandValue() == 21) { winnings += bet * blackjackPayoff; it-&gt;isBlackjack = true; } else { allNats = false; if(it-&gt;getHandValue() &gt; 21) it-&gt;busted = true; } } if(!allNats) { while(dealer.getHandValue() &lt;= 17) { if(dealer.getHandValue() == 17) { //dealer has 17 and doesnt hit soft 17s so hes not going to draw anymore cards if( !hitSoft17 || dealer.cards() != 2 || !(dealer.hand.at(0) == ACE || dealer.hand.at(1) == ACE) ) break; } dealer.addCard( shoe.pullCard() ); } } for(std::vector&lt;Hand&gt;::iterator it = player.begin(); it != player.end(); ++it) { if(!it-&gt;isBlackjack) { if(it-&gt;busted) { if(it-&gt;doubled) winnings -= 2.0 * bet; else winnings -= bet; } else if(dealer.getHandValue() &gt; 21 || dealer.getHandValue() &lt; it-&gt;getHandValue()) { if(it-&gt;doubled) winnings += 2.0 * bet; else winnings += bet; } else if(dealer.getHandValue() &gt; it-&gt;getHandValue()) { if(it-&gt;doubled) winnings -= 2.0 * bet; else winnings -= bet; } } } //only other scenario is a push which we dont do anythign for return winnings; } void Table::simulate(std::string fileName, int hands) { int i(0), countHL; double trueCountHL; std::ofstream ofs(fileName); Action action; while(i &lt; hands) { deal(); VisibleCards vc(player[0].at(0), player[0].at(1), dealer.at(0)); while(isCurrentGame()) { int j(0), q(1); countHL = shoe.getCountHL(); trueCountHL = shoe.getTrueCountHL(); for(int l = 0; l &lt; q; ++l) { while(player[l].active) { if(player[l].cards() == 2) action = getBasicStrategy(player[l].getHandValue(), dealer.at(0).getCardValue(), player[l].at(0).getCardValue(), player[l].at(1).getCardValue()); else action = getBasicStrategy(player[l].getHandValue(), dealer.at(0).getCardValue()); switch(action) { case HIT: hit(j); break; case DOUBLE: hit(j); if(player[l].cards() == 3) { player[l].doubled = true; player[l].active = false; } break; case SPLIT: if(player.size() &lt;= 4) { split(j); ++q; } else hit(j); break; case STAND: player[l].active = false; break; } ++j; } } } double winnings = stand(); balance += winnings; ofs &lt;&lt; std::endl &lt;&lt; std::fixed &lt;&lt; vc &lt;&lt; "," &lt;&lt; winnings &lt;&lt; "," &lt;&lt; std::setprecision(2) &lt;&lt; trueCountHL &lt;&lt; "," &lt;&lt; balance &lt;&lt; "," &lt;&lt; std::setprecision(0) &lt;&lt; countHL &lt;&lt; "," &lt;&lt; shoe.getRemainingDecks(); ofs &lt;&lt; std::endl &lt;&lt; 1; //BlackjackData bjd(winnings, balance, shoe.getTrueCountHL(), shoe.getCountHL(), HIT); //strat.addData(vc, bjd); ++i; } strat.print(fileName); } </code></pre>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload