Not Using References Properly

Discussion in 'C++' started by A_StClaire_@hotmail.com, Nov 21, 2005.

  1. Guest

    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 21, 2005
    #1
    1. Advertising

  2. Jim Langston Guest

    <> wrote in message
    news:...
    > 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;
    };
    Jim Langston, Nov 21, 2005
    #2
    1. Advertising

  3. Heinz Ozwirk Guest

    <> schrieb im Newsbeitrag
    news:...
    ....
    > 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
    Heinz Ozwirk, Nov 21, 2005
    #3
  4. 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
    John Harrison, Nov 21, 2005
    #4
  5. Guest

    ah. had nothing to do with references whatsoever!

    thx for your help, all.
    , Nov 21, 2005
    #5
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Roger Leigh
    Replies:
    8
    Views:
    415
    Karl Heinz Buchegger
    Nov 17, 2003
  2. Replies:
    3
    Views:
    435
    Victor Bazarov
    Nov 10, 2004
  3. DanielEKFA
    Replies:
    8
    Views:
    589
    DanielEKFA
    May 16, 2005
  4. Replies:
    8
    Views:
    694
    Bruno Desthuilliers
    Dec 12, 2006
  5. Lars Willich
    Replies:
    13
    Views:
    821
    Ian Shef
    Oct 23, 2007
Loading...

Share This Page