passing *this pointer from inside one class to a map in another

Ok, hopefully this is going to me some sense to someone because I am losing lots of hair over it now.

I have an 'Application' class, with one instance defined as a global. This is basically a starting point to avoid having lots of globals.

The application is the server side of a multiplayer game, so I have another class called 'Player' that holds information about players. (of which there can be lots)

Inside the Application class, I define a list in which I create my player objects, one for each player.

I am trying to also use maps to create a sort of lookup table to quickly find players in the list based on a specific piece of information about the player. (in this case, username)

In the constructor of the Player object, I am trying to store a pointer to 'this' along with the players username in the map called _Player_Logins.

When doing this, I receive 'Segmentation Fault'.

I am really at a loss as to why I am getting this so I am hoping someone else might know.

Here is a very basic example of what I am trying to do. (code is tested)

main.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <string>

using namespace std;

class Player {
public:
    string login;
    string password;

    Player();
};

class Application {
public:
    list<Player *> _Players;
    map<string, Player *> _Player_Logins;

    Application();
};

int main();


main.cpp
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
#include <list>
#include <map>
#include <iostream>

#include "main.h"

using namespace std;

Application *mApp;

Application::Application() {
    _Players.push_back(new Player());
};

Player::Player() {
    login="testLogin";
    password="secret";
    mApp->_Player_Logins[login]=this;
};

int main() {
    mApp=new Application();
    cout << mApp->_Player_Logins["testLogin"]->password << "\n";
    return(0);
};


My sincere thanks to anyone who spends a little time looking at this.
1
2
3
4
5
6
7
8
//main
mApp=new Application(); //calls Application::Application();

//Application()
 _Players.push_back(new Player()); //calls Player::Player();

//Player()
mApp->_Player_Logins[login]=this;//mApp still points to garbage, crash 


Also:
_ Don't put using namespace in headers (it kills the purpose)
_ Include everything you need, where you need it (you use map and list in the header)
_ Use header guards (check http://www.cplusplus.com/forum/articles/10627 )
Last edited on
ne555 - thank you so much, you explained my problem and now it works.

could someone point me to something about (or briefly point out) why I should not use 'using namespace std' in the headers? Without it I need to precede the string, list and map types with std::. (its no biggie, just seems like something that could easily be avoided - i am obviously missing some other side effect of using namespace in headers.)

Apologies for the messed up includes and missing header guards. The includes were wrong - the header guards were only missing because it was a simple test and in my main program I do use them.

It did take me a few seconds to understand what I had done wrong based on your very good response so I will post below a little more detail and working example for anyone else who may come across this.


The main issue ne555 pointed out is that the call to mApp global is being made from within the constructor of mApp itself. Because the constructor is still being executed, the object has not yet been stored in the mApp global so when I try to use it - it is still garbage.

My solution was to create mApp and then create a new member function called init() which is called *after* "mApp=new Application();" where mApp has actually been stored.

Here is my updated code reflecting all of the very good suggestions ne555 made.

main.h
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
#ifndef main_h
#define main_h

#include <string>
#include <list>
#include <map>


class Player {
public:
    std::string login;
    std::string password;

    Player();
};

class Application {
public:
    std::list<Player *> _Players;
    std::map<std::string, Player *> _Player_Logins;

    void init();
};
int main();

#endif 


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

#include "main.h"

using namespace std;

Application *mApp;

void Application::init() {
    _Players.push_back(new Player());
};

Player::Player() {
    login="testLogin";
    password="secret";
    mApp->_Player_Logins[login]=this;
};

int main() {
    mApp=new Application();
    mApp->init();
    cout << mApp->_Player_Logins["testLogin"]->password << "\n";
    return(0);
};


Again, thank you so much ne555. You solved my problem.
Topic archived. No new replies allowed.