I am developing a tic-tac-toe board game in c++ for learning purposes, and I am passing a char** to a function that assigns the given parameter an array of pointers which stores a players name.
Upon variable assignment, I am able to print the results of the initialized variable in the function call to void initPlayerNames(char** playerNames) but when I return to the caller function the program does not print the results.
My understanding is that a pointer variable stores the address of another data structure, therefore I expect to print the results of the pointer variable after it has been modified in the function call.
Please help me understand where I am making a mistake
void initPlayerNames(char** playerNames) {
const int playerNameLength = 100;
cout << "Player one, enter your name: ";
char p1[playerNameLength];
cin.getline(p1, playerNameLength);
cout << "Player two, enter your name: ";
char p2[playerNameLength];
cin.getline(p2, playerNameLength);
char* names[2] = {p1, p2};
playerNames = names;
cout << "Player 1 = " << playerNames[0] << endl;
cout << "Player 2 = " << playerNames[1] << endl;
};
void game() {
char** playerNames = nullptr;
cout << "Welcome! \n";
initPlayerNames(playerNames);
cout << "Player 1 = " << playerNames[0] << endl;
cout << "Player 2 = " << playerNames[1] << endl;
};
Output
Player one, enter your name: Kevin Patel
Player two, enter your name: Steve Jobs
Player 1 = Kevin Patel
Player 2 = Steve Jobs
>Solution :
The pointer playerNames is set like this:
char* names[2] = {p1, p2};
playerNames = names;
However, when the function initPlayerNames() exits, names, p1and p2 are all destroyed and thus playerNames points at unallocated memory.
Besides, playerNames itself in initPlayerNames() is a variable which is destroyed when the function exits (like in a function void func(int a), changes to a are not reflected in the caller function).
To fix this:
-
Declare the involved variables as
staticwhich means they will be allocated also when the function is not running. Note, however, that this is mostly to illustrate the lifetime issue, this solution is not without problems (not safe in multi-threaded applications and exposes seemingly local variables outside their function – it is like using global variables). -
Pass a pointer or reference to
playerNames. Being old-fashioned, I prefer a pointer so it is clearer that the passed argument may be changed:
void initPlayerNames(char*** playerNames) {
const int playerNameLength = 100;
cout << "Player one, enter your name: ";
static char p1[playerNameLength];
cin.getline(p1, playerNameLength);
cout << "Player two, enter your name: ";
static char p2[playerNameLength];
cin.getline(p2, playerNameLength);
static char* names[2] = {p1, p2};
*playerNames = names;
cout << "Player 1 = " << (*playerNames)[0] << endl;
cout << "Player 2 = " << (*playerNames)[1] << endl;
};
and call the function like this:
initPlayerNames(&playerNames);