struct pointer vector gets weird after adding another struct pointer to it

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#include <iostream>
#include <vector>

using namespace std;
struct player{
    bool online;
};
vector<player> players;
vector<player*> main_queue;

int main(int argc, const char * argv[])
{
    player new_player;
    new_player.online = true;
    players.push_back(new_player);
    main_queue.push_back(&players[0]);
    cout << "Player 1 is " << main_queue[0]->online << endl;
    player new_player_2;
    new_player_2.online = true;
    players.push_back(new_player);
    main_queue.push_back(&players[1]);
    cout << "Player 1 is " << main_queue[0]->online << endl;
    cout << "Player 2 is " << main_queue[1]->online << endl;
    return 0;
}


Output comes out as:

1
2
3
Player 1 is 1
Player 1 is 0
Player 2 is 1


Why is this??
Last edited on
reallocation
What is a more better and safer way to ensure that it is always pointing towards it? I wouldn't want to call main_queue[0] = &players[0]; everytime because players get added to main_queue all the time.
Last edited on
1- Keep the index
A- Reserve enough space
\alpha- Change the container type to one that does not reallocate (by instance `std::list')
\aleph- Just use the same container object
My plan is that players vector will always add and remove players (because of disconnect), so keeping the index would be very messy and sometimes the members get different positions when players vector removes a struct player.

1
2
3
4
vector<int> main_queue;
main_queue.push_back(0); //Index
main_queue.push_back(1); //Index
main_queue.push_back(2); //Index 


on the other hand I will..

1
2
3
4
5
6
vector<player> players
player new_player;
players.push_back(new_player); //Player 1
players.push_back(new_player); //Player 2
players.push_back(new_player); //Player 3
players.erase(players.begin()+1); //Erasing index 1 


it would make main_queue[1]'s index point to player 3.

I am trying to use list.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#include <iostream>
#include <vector>
#include <list>

using namespace std;
struct player{
    bool online;
};
vector<player> players;
list<player*> main_queue;

int main(int argc, const char * argv[])
{
    player new_player;
    new_player.online = true;
    players.push_back(new_player);
    main_queue.push_back(&players[0]);
    player new_player_2;
    new_player_2.online = true;
    players.push_back(new_player);
    main_queue.push_back(&players[1]);
    list<player*>::iterator it;
    for(it = main_queue.begin(); it != main_queue.end(); it++){
        cout << "Player " << (*it) << " is "<< (*it)->online << endl;
    }
    
    players[0].online = false; //CHANGE TO OFFLINE!
    
    for(it = main_queue.begin(); it != main_queue.end(); it++){
        cout << "Player " << (*it) << " is "<< (*it)->online << endl;
    }
    

    return 0;
}



Output comes out as:

1
2
3
4
5
Player 0x1001000e0 is 1
Player 0x100103b11 is 1

Player 0x1001000e0 is 1
Player 0x100103b11 is 1
Last edited on
Well I guess this solution works!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#include <iostream>
#include <vector>
#include <list>

using namespace std;


struct player{
    bool online;
};

vector<player*> players;
vector<player*> main_queue;

int main(){
    player *new_player = new player;
    new_player->online = false;
    players.push_back(new_player);
    main_queue.push_back(players[0]);
    cout << main_queue[0]->online << endl;
    players[0]->online = true;
     cout << main_queue[0]->online << endl;
    
    return 0;
}


I'll just uncomplicate it by just making players vector pointers of player* itself then pass it along.
Last edited on
Could also use a deque or a list, they don't invalidate pointers/references to the elements on push_back.
I'll just uncomplicate it by just making players vector pointers of player* itself then pass it along.


Except, you actually complicated it by introducing manually managed dynamic memory. Where did you deallocate that, by the way?

You changed the wrong container to list in your previous post. A std::deque would probably be a better choice than a list.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#include <iostream>
#include <vector>
#include <deque>

using namespace std;
struct player{
    bool online;

    player(bool isOnline = true) : online(isOnline) {}
};

std::deque<player> players;
vector<player*> main_queue;

int main(int argc, const char * argv[])
{
    // add a new player:
    players.push_back(player()) ;
    main_queue.push_back(&players.back()) ;

    cout << "Player 1 is " << main_queue.front() << endl;

    players.push_back(player());
    main_queue.push_back(&players.back());

    for ( unsigned i=0; i != main_queue.size() ; ++i )
    {
        std::cout << "Player " << i+1 << " at " << main_queue[i] 
            << " is " << (main_queue[i]->online ? "online\n" : "not online\n") ;
    }
}

@OP: ¿what's the purpose of `main_queue' ?
> players vector will always add and remove players
¿how should the queue be affected by that?
Topic archived. No new replies allowed.