Hello, I'm kind of new to C++ development in linux and I'm trying to make a multiplayer game. I know that it is a bit of complex program to start but I have some background on this type of program from other languages so I guess the most difficult part is taming the language.

Although I'm programming a multiplayer game, my doubts are about the best way to handle the memory and avoid leaks in C++.

My doubts are about allocating memory for the client objects and for the game tables. For the client objects I've read that the std containers handle the memory allocation for me. I don't know if this memory is allocated on heap so I've decided to use a map of pointers (with the socket fd as key) to client object. This way, I have something like this when a client connect and disconnect:

Daemon.cpp

map<int,Client*> clientList;

//Do server stuff

//Add connected client to list
void onConnect(int socketFd) {
clientList[socketFd] = new Client();
}

//remove connected client from list
void onDisconnect(int socketFd) {
delete clientList[socketFd];
clientList.erase(socketFd);
}

The Client class is a simple class that has a virtual destructor, some client parameters (like IP, connected time, etc) and some methods (like send, etc). Is this the best way to keep track of clients without memory problems? I guess I still have to add exceptions handling on new Client() allocations...

The second part, and I guess the most difficult for me, is about the game tables. Clients can enter and leave tables of games. I have a table class with a lot of parameters, constants and methods. I'm creating all the game tables on start up on the same Daemon.cpp described above:

Daemon.cpp

GameTable *tables;

int main() {
tables = new Chess[MAX_NUMBER_OF_TABLES];
}

Some explanations: GameTable is the base class for all games. It is an interface with base parameters and virtual game functions (like doCommand, addClient, removeClient, etc). Chess class is the implementation of the chess game, it inheritance (sorry bad english) from GameTable. Questions:

1) Is this the best way (memory) to handle it?
2) Chess class has a lot of parameters, when I allocate the table list of Chess objects do the memory for all objects already allocated or I have to allocate and dealocate inside Chess class (with constructors and destructors)?

My third question is how to add and remove clients to/from tables. First I thought in creating a simple vector with clients like:

GameTable.h

vector <Client> clientInTable;

Chess.cpp

//Add client to table
void addClient(Client &client) {
clientInList.push_back(client);
}

//remove client from table
void removeClient(Client &client) {
//search client on list, when found get position pos
clientList.erase(pos);
}

Soon I noticed that when I remove the client its destructor was called. It must not happen! Than I thought in use a vector of pointers like:

GameTable.h

vector <Client*> clientInTable;

Chess.cpp

//Add client to table
void addClient(Client *client) {
clientInList.push_back(client);
}

//remove client from table
void removeClient(Client *client) {
//search client on list, when found get position pos
clientList[pos] = NULL;
}

Is this the best way to handle it? Thanks everybody for the help.

Nick Evan commented: Good first post +12
GameTable.h

vector <Client*> clientInTable;

Chess.cpp

//Add client to table
void addClient(Client *client) {
clientInList.push_back(client);
}

//remove client from table
void removeClient(Client *client) {
//search client on list, when found get position pos
clientList[pos] = NULL;
}

Based on what I see, you have created 2 huge memory leaks. There are two (2) things in this that concern me:

1.) You're pushing onto the vector, but you're not erasing from the vector. This means that your vector will be continuously growing, until it's out of control. I'm not sure this is "technically" a memory leak, but it definitely is wasted resources. As I understand it, push_back() places an object in the first available slot in the vector. If the current capacity is not sufficient, it automatically re-allocates a new (larger) memory block and copies the vector into that new block then appends the new data. This requires special constructor and destructor considerations that I am not yet familiar with.

2.) It sounds like you plan to continue accessing the user object(s) after they leave a board/game. After you NULL the pointer(s), how do you plan to continue to access the user object that was pointed to by that pointer? If you NULL the pointer, you lose access to your object unless you have another copy of the pointer stored elsewhere. A NULL pointer is still a valid pointer, it just doesn't point to anything. As a result, you have several vector elements that point to nothing and you have orphaned objects (users).

I'm a little unsure about what would be a good approach to correcting this. I think that would depend on your intent with the software. Is there a reason each individual board would have more than 2 users?

If not, I would suggest that you create a 2-element vector of User pointers then use assignments rather than the push_back() method. This will give you more control over your system resources and the calling of constructors and destructors. This would also allow you to check a game for players and determine if it is full or not.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.