2
typedef struct {
    char *title;
    char *desc;
} RoomData;
RoomData roomData;
GameGetCurrentRoomTitle(roomData.title);

//INSIDE THE GAME.C FILE
int GameGetCurrentRoomTitle(char *title) {
    title = &gameData.title[0];
    return strlen(title);
}

So for some reason when I call the GameGetCurretRoomTitle() function it isn't properly being able to print out the contents of roomData.title, it prints NULL. BUT when I print out the 'title' var inside the function itself it works... I have included all the correct files, headers, and ALL the syntax is correct in the full code...

4 Answers 4

1

Parameters of a function are its local variables. You may imagine this function definition

int GameGetCurrentRoomTitle(char *title) {
    title = &gameData.title[0];
    return strlen(title);
}

and its call

GameGetCurrentRoomTitle(roomData.title);

like

GameGetCurrentRoomTitle(roomData.title);
//...
int GameGetCurrentRoomTitle() {
    char *title = roomData.title;
    title = &gameData.title[0];
    return strlen(title);
}

After exiting the function its local variable title will be destroyed.

If you want that the original pointer would be changed you have to pass its address. In this case the function definition and its call will look like

GameGetCurrentRoomTitle( &roomData.title );
//...
int GameGetCurrentRoomTitle( char **title ) {
    *title = &gameData.title[0];
    return strlen( *title );
}
Sign up to request clarification or add additional context in comments.

Comments

1

C uses pass-by-value for function argument passing. If you want to change the value of roomData.title variable itself from GameGetCurrentRoomTitle() function, you've to pass a pointer to roomData.title. Then you can use strdup() to copy the contents of gameData.title[0] to title inside GameGetCurrentRoomTitle(). You need to remember to free the pointer afterwards.

Otherwise, you can allocate memory to title before passing that to GameGetCurrentRoomTitle() and then inside GameGetCurrentRoomTitle()use strcpy() to copy the string from gameData.title[0].

You need to change GameGetCurrentRoomTitle() function accrodingly.

Comments

0

Setting the value of the variable inside the function doesn't change the value of the variable in the caller.

You need to use strcpy to copy the title to the buffer passed into the function. Don't just change the local pointer.

Comments

0

Assuming that gameData.title is an array of pointers to char arrays

Then gameData.title[0] holds a pointer to a char array that exists "somewhere" in memory. Let's say the title is "Foobar" and this is where it is in memory:

[ ][ ][ ][ ][F][o][o][b][a][r][\0][ ][ ][ ][ ]

Let's say that the bytes, or chars, immediately before and after the title are unset and unused by the program at this very moment in time, and that the empty slots above for them means just that.

Now, let's call the pointer to a char array that is in gameData.title[0] for p1. It is pointing at the "Foobar" char array, like this:

[ ][ ][ ][ ][F][o][o][b][a][r][\0][ ][ ][ ][ ]
             ^
             |
             +-----------+
                         |
   [ ][ ][ ][ ][ ][ ][ ][p1][p2][p3][p4][ ]

The pointers p2-p4 are the rest of the char pointers in the gameData.title array.

Now, you have 2 more interesting pointers in your scenario. First, the roomData.title char pointer. Let's call it pA for simplicity. When you pass it to GameGetCurrentRoomTitle, it's unset and points at an undefined char in the memory space:

[ ][ ][ ][ ][F][o][o][b][a][r][\0][ ][ ][ ][ ]
             ^
             |
             +------------+
                          |
   [ ][pA][ ][ ][ ][ ][ ][p1][p2][p3][p4][ ]
       |
       +---------+
                 |
                 v
             [ ][ ][ ][ ]

Second, the GameGetCurrentRoomTitle title char pointer parameter. Let's call it pB for simplicity. When you pass pA as an argument to GameGetCurrentRoomTitle, its value is copied to pB. Its value is not the contents of the memory it points at, but the address it points at. This means that pB will point at the same undefined char in the memory space as pA does:

[ ][ ][ ][ ][F][o][o][b][a][r][\0][ ][ ][ ][ ]
             ^
             |
             +-------------+
                           |
   [ ][pA][ ][ ][ ][pB][ ][p1][p2][p3][p4][ ]
       |            |
       +---------+--+
                 |
                 v
             [ ][ ][ ][ ]

Next, in the body of GameGetCurrentRoomTitle, you reassign pB (the local title char pointer) to point at the same memory location as p1 (the pointer to a char array that is in gameData.title[0]):

[ ][ ][ ][ ][F][o][o][b][a][r][\0][ ][ ][ ][ ]
             ^
             |
             +------+------+
                    |      |
   [ ][pA][ ][ ][ ][pB][ ][p1][p2][p3][p4][ ]
       |            
       +---------+
                 |
                 v
             [ ][ ][ ][ ]

And, when GameGetCurrentRoomTitle finally returns to its caller, pA is still pointing at the same undefined memory location.

The fix you miss is to pass a pointer to pA to GameGetCurrentRoomTitle instead of just pA itself, and instead of reassigning pB to point at the same memory location as p1, you should dereference pB and assign p1 to that memory location, which is the memory location where the value of the pA variable is stored. That way, when GameGetCurrentRoomTitle returns, pA will see the string you expected.

With "graphics", the new situation would be that pB doesn't point at a char array, but at a pointer to a char array. We know that pA is that pointer to a char array:

[ ][ ][ ][ ][F][o][o][b][a][r][\0][ ][ ][ ][ ]
             ^
             |
             +-------------+
                           |
   [ ][pA][ ][ ][ ][pB][ ][p1][p2][p3][p4][ ]
       ^            |
       |            |
       +------------+

By assigning something to the dereferenced pB, you effectively assign to the memory location it points at, not to pB itself. So assigning p1 to the deferenced pB is the same as assigning it to pA in this scenario:

[ ][ ][ ][ ][F][o][o][b][a][r][\0][ ][ ][ ][ ]
             ^
             |
       +-----+-------------+
       |                   |
   [ ][pA][ ][ ][ ][pB][ ][p1][p2][p3][p4][ ]

And in code:

GameGetCurrentRoomTitle(&roomData.title); // pass pointer to 'pA'

int GameGetCurrentRoomTitle(char **title) // 'pB' is a pointer to pointer
{ 
    *title = &gameData.title[0];         // assign 'p1' to dereferenced 'pB'
    return strlen(*title);               // measure dereferenced 'pB'
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.