Question

I'm working on a game and I ran into a strange little issue... I was wondering if anyone here would be able to figure this out and explain it to me (it's eating me up!)

Firstly, here's the relevant code.

// even if this data is not set, it returns ""
// so it's pretty much never null
// but if the function returns something, 
// it will be the string representation of a 64bit unsigned int
const char* c_KickID = GetGameData("kick_member_id");

//gets my ID, works fine.
unsigned long long myID = GetMyID();

if(c_KickID != NULL)
{
    //here i convert it to a unsigned 64-bit int
    unsigned long long kickID;
    std::stringstream ss(c_KickID);
    ss >> kickID;

    //now I compare the IDs...
    if (myID == kickID)
    {
        //kick player
    }
}

The game is a 1 vs 1 multiplayer game. This containing function is a callback function that runs whenever something noteworthy has happened (such as kicking a player, or starting a game). I have 2 computers I am testing the online stuff on (a Windows 7 machine and Windows XP machine).

In this case, a weird bug reliably appears when both players press "Start Game" at the same time. The Windows XP machine player would be kicked (via the code above) - which suggests GetGameData("kick_member_id") returned his ID... except it doesn't.

Debugging:

  • I've commented out the code that sets the GameData "kick_member_id" value (ie. Disabled kicking) to make sure - and the bug continues to occur. The host is not kicking the client.
  • I've outputted c_KickID to a file and it's empty (The XP machine doesn't have Visual Studio so I can't really set breakpoints on it, so I just output its contents to a file).
  • I tried to explicity kick the XP player. Their ID was successfully written to the output file and they were kicked, as expected.
  • I've outputted kickID to a file and it IS equal to myID, which is explains why the if (myID == kickID) passes.

To recap:

// This returns an empty char array
const char* c_KickID = GetGameData("kick_member_id");

//get my id... 
unsigned long long myID = GetMyID();

//Then I run this. Keeping in mind, c_KickID is empty
unsigned long long kickID;
std::stringstream ss(c_KickID);
ss >> kickID; //<--- now kickID == myID

So... when converting the empty c_KickID into an unsigned long long, it is set to myID... How is this even possible? I'm completely losing my mind!

I HAVE fixed the issue by converting the char * to a std::string and checking if that's empty or not, if it is empty then I just bypass this code. But I still have no idea what the problem ACTUALLY was. I'm losing sleep over this!!!

Was it helpful?

Solution

if c_KickID is an empty null-terminated string, the stringstream ss will be empty as well, and ss >> kickID won't have any effect.

Since kickID is uninitialized, its value is unspecified and using it is undefined. One possible outcome is that it has whatever random bits were at that memory location in the stack, which could be equal to myID.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top