By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
454,505 Members | 1,761 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 454,505 IT Pros & Developers. It's quick & easy.

Not Using References Properly

P: n/a
hi,

my poker game does

playersActiveInRound = players;

at the start of every round where both are vector<Player> (i.e.,
containers of a user-defined class). the latter vector is everyone who
hasn't run out of money yet.

in a round, when someone folds I wish to remove them from
playersActiveInRound by calling

void Game::DropPlayer(Player& targetPlayer)
{

for(posPlayer = playersActiveInRound.begin(); posPlayer !=
playersActiveInRound.end(); ++posPlayer)
{
if((*posPlayer).GetFullName() == targetPlayer.GetFullName())
{
playersActiveInRound.erase(posPlayer);
}
}

}

and feeding it the Player identifier.

can anyone tell me why I get a crash everytime this function runs?

thx a lot

Nov 22 '05 #1
Share this Question
Share on Google+
4 Replies


P: n/a
<A_*********@hotmail.com> wrote in message
news:11**********************@f14g2000cwb.googlegr oups.com...
hi,

my poker game does

playersActiveInRound = players;

at the start of every round where both are vector<Player> (i.e.,
containers of a user-defined class). the latter vector is everyone who
hasn't run out of money yet.

in a round, when someone folds I wish to remove them from
playersActiveInRound by calling

void Game::DropPlayer(Player& targetPlayer)
{

for(posPlayer = playersActiveInRound.begin(); posPlayer !=
playersActiveInRound.end(); ++posPlayer)
{
if((*posPlayer).GetFullName() == targetPlayer.GetFullName())
{
playersActiveInRound.erase(posPlayer);
}
}

}

and feeding it the Player identifier.

can anyone tell me why I get a crash everytime this function runs?

thx a lot

The following is a fully functioning program that uses your method without
change. Your error must be somewhere else in code you haven't shown.

#include <vector>
#include <fstream>
#include <iostream>
#include <string>
#include <cmath>
#include <cassert>
#include <windows.h>
#include <list>

class Player
{
public:
std::string GetFullName() { return FullName; };
void SetFullName( std::string Name ) { FullName = Name; };
private:
std::string FullName;
};

class Game
{
public:
void InsertPlayer( Player player ) { playersActiveInRound.push_back(
player ); };
void DropPlayer(Player& targetPlayer);
void ListPlayers();
private:
std::vector<Player> playersActiveInRound;
std::vector<Player>::iterator posPlayer;
};

void Game::DropPlayer(Player& targetPlayer)
{
for(posPlayer = playersActiveInRound.begin(); posPlayer !=
playersActiveInRound.end(); ++posPlayer)
{
if((*posPlayer).GetFullName() == targetPlayer.GetFullName())
{
playersActiveInRound.erase(posPlayer);
}
}
}

void Game::ListPlayers()
{
for(posPlayer = playersActiveInRound.begin(); posPlayer !=
playersActiveInRound.end(); ++posPlayer)
{
std::cout << (*posPlayer).GetFullName() << std::endl;
}
}

int main()
{
Game MyGame;
Player Temp;
Temp.SetFullName( "Jim" );
MyGame.InsertPlayer( Temp );
Temp.SetFullName( "Joe" );
MyGame.InsertPlayer( Temp );
Temp.SetFullName( "Bob" );
MyGame.InsertPlayer( Temp );
MyGame.ListPlayers();

std::cout << "Deleting..." << std::endl;
Temp.SetFullName("Joe");
MyGame.DropPlayer( Temp );

MyGame.ListPlayers();

char wait;
std::cin >> wait;
};
Nov 22 '05 #2

P: n/a
<A_*********@hotmail.com> schrieb im Newsbeitrag
news:11**********************@f14g2000cwb.googlegr oups.com...
....
for(posPlayer = playersActiveInRound.begin(); posPlayer !=
playersActiveInRound.end(); ++posPlayer)
{
if((*posPlayer).GetFullName() == targetPlayer.GetFullName())
{
playersActiveInRound.erase(posPlayer);
}
}


You must not increment the iterator if you remove an element from the
vector. Erase moves all elements after the removed one towards the vector's
front and the iterator will address the first element originally following
the removed one. Then, as part of the for statement, you move the iterator
to the next place in the vector. In the best case this will skip one
element. In the worst case, if the element at the end of the vector has been
removed, your iterator will never be equal to end().

There are several ways to solve your problem. If all the players have
different names and you always remove at most one player, the best way seems
to separate searching and removing. Something like

Iterator it = Find(playersActiveInRound, targetPlayer.GetFullName());
if (it != playersActiveInRound) playersActiveInRound.erase(it);

HTH
Heinz
Nov 22 '05 #3

P: n/a
A_*********@hotmail.com wrote:
hi,

my poker game does

playersActiveInRound = players;

at the start of every round where both are vector<Player> (i.e.,
containers of a user-defined class). the latter vector is everyone who
hasn't run out of money yet.

in a round, when someone folds I wish to remove them from
playersActiveInRound by calling

void Game::DropPlayer(Player& targetPlayer)
{

for(posPlayer = playersActiveInRound.begin(); posPlayer !=
playersActiveInRound.end(); ++posPlayer)
{
if((*posPlayer).GetFullName() == targetPlayer.GetFullName())
{
playersActiveInRound.erase(posPlayer);
}
}

}

and feeding it the Player identifier.

can anyone tell me why I get a crash everytime this function runs?

thx a lot


This is a case where you have to look at exactly what you wrote instead
of what you think you wrote.

Specifically what do you think happens to posPlayer when you erase a player

for(...; ++posPlayer)
{
if(...)
{
playersActiveInRound.erase(posPlayer);
}
}

Think about it, you are erasing a player and moving the iterator forward
in the same iteration.

The right way is like this

while (...)
{
if (...)
posPlayer = playersActiveInRound.erase(posPlayer);
else
++posPlayer;
}

erase returns an iterator to the element after the erased element.

john
Nov 22 '05 #4

P: n/a

ah. had nothing to do with references whatsoever!

thx for your help, all.

Nov 22 '05 #5

This discussion thread is closed

Replies have been disabled for this discussion.