0

I'm struggling to get one struct to point to another which is dependent on the arguments passed into the command line, the problem is, that struct me is appearing to be pointing correctly to the desired struct in the initialise game function, (which is called by parse args which is called in main), however, when I print their address after the function call, in main, it appears not to have changed (following output) if the player is A:

Before initialise: 0x7f8a88403990, 0x7f8a884039f0, 0x7f8a88403a50, 0x7f8a88403ab0, 0x7f8a88403b10
After initialise: 0x7f8a884039f0, 0x7f8a884039f0, 0x7f8a88403a50, 0x7f8a88403ab0, 0x7f8a88403b10
After parse args: 0x7f8a88403990, 0x7f8a884039f0, 0x7f8a88403a50, 0x7f8a88403ab0, 0x7f8a88403b10

int main (int argc, char *argv[]) {

Player *me = NULL, *playerA = NULL;
Player *playerB = NULL, *playerC = NULL, *playerD = NULL;

me = malloc(sizeof(*me));
playerA = malloc(sizeof(*playerA));
playerB = malloc(sizeof(*playerB));
playerC = malloc(sizeof(*playerC));
playerD = malloc(sizeof(*playerD));

parse_args(me, playerA, playerB, playerC, playerD, argv);

//should be pointing to the same memory location
printf("After parse args: %p, %p, %p, %p, %p\n", me, playerA, playerB, playerC, playerD);

}

void parse_args(Player *me, Player *a, Player *b, Player *c, Player *d,
            char *argv[]) {
initialise_game(*tempChar, tempNum, me, a, b, c, d);

}

void initialise_game(char playerID, int numPlayers, Player *me, Player *a,
                 Player *b, Player *c, Player *d) {
printf("Before initialise: %p, %p, %p, %p, %p\n", me, a, b, c, d);

switch((int)playerID) {
    case 'A':
        me = a;
        break;
    case 'B':
        me = b;
        break;
    case 'C':
        if (numPlayers < 3) {
            exit_prog(EXIT_PLAYERID);
        }
        me = c;
        break;
    case 'D':
        if (numPlayers < 4) {
            exit_prog(EXIT_PLAYERID);
        }
        me = d;
        break;
}

printf("After initialise: %p, %p, %p, %p, %p\n", me, a, b, c, d);

}
user3603183
  • 313
  • 1
  • 2
  • 9

2 Answers2

1

Pointers get passed by value. That means you can't modify them in the body of a function(). See this StackOverflow question/answer

I think you wanted to do something like:

void parse_args(Player **me, Player *a, Player *b, Player *c, Player *d, char *argv[]) {
    initialise_game(*tempChar, tempNum, me, a, b, c, d);
}

void initialise_game(char playerID, int numPlayers, Player **me, Player *a,
             Player *b, Player *c, Player *d) 
{
    printf("Before initialise: %p, %p, %p, %p, %p\n", me, a, b, c, d);
    switch((int)playerID) {
    case 'A':
        *me = a;
        break;
    case 'B':
        *me = b;
    break;
    case 'C':
        if (numPlayers < 3) {
            exit_prog(EXIT_PLAYERID);
        }
        *me = c;
        break;
    case 'D':
        if (numPlayers < 4) {
            exit_prog(EXIT_PLAYERID);
        }
        *me = d;
        break;
}

Your call to parse_args would need to pass a pointer to a pointer for me:

parse_args(&me, playerA, playerB, playerC, playerD, argv);
Community
  • 1
  • 1
Michael Petch
  • 43,801
  • 8
  • 98
  • 174
  • Thank you for a precise clear answer, I understand now how this work (sorry it's a bit tricky to get my head around) – user3603183 Sep 25 '14 at 22:50
  • Passing pointers by value and trying to modify them is tricky - it catches many newer C programmers off guard. The Stackoverflow question I linked to can help you immensely. But if you ever want to modify a pointer in a function you'll need to pass its address and then de-reference in the function to do assignment – Michael Petch Sep 25 '14 at 22:54
0

You need to use a pointer to a pointer to structure for function parameters (e.g., Player **x). Using a pointer to the structure you can only modify the structure object, not the pointer object. Remember all function arguments are passed by value in C, if you modify the pointer argument in the function you are only modifying a copy of the pointer.

ouah
  • 138,975
  • 15
  • 262
  • 325
  • Which functions would I need those paramaters for? I've just tried for parse_args on it's own, initialise_game on it's own, and both together, but they don't seem to be working... – user3603183 Sep 25 '14 at 22:33
  • @user3603183 all of them, but you have to correctly pass the arguments to the functions and correctly dereference the pointers in the functions. Enable the warnings in your compiler and fix them if there is any. – ouah Sep 25 '14 at 22:35