Mysterious Heisenbug?

So, I am doing a snake game with teleporters and regular mice. I had such a loop:

while(snake.alive() && miceEaten < micePerLevel)
{
    displayInfo(lives, score, level, micePerLevel - miceEaten);
    //some code
    if(miceEaten())
    {
        //update score...
    }
    //more stuff...
}

The problem with the code above was that it was displayInfocalled before the score was updated, and therefore, after eating, the mouse had to wait until the cycle started again to see how its score was updated. So I moved one line of code to the bottom of the function:

while(snake.alive() && miceEaten < micePerLevel)
{
    //some code
    if(miceEaten())
    {
        //update score...
    }
    //more stuff...
    displayInfo(lives, score, level, micePerLevel - miceEaten);
}

and teleporters stop working! The program crashes whenever a snake reaches a teleport. And displayInfouses the following code:

stringstream s;
s << "LEVEL " << left << setw(12) << level << "LIVES: " << setw(12) << lives << "MICE LEFT: " << setw(12) << miceLeft
    << "SCORE: " << setw(13) << score;
printLine(0, s.str(), WHITEONBLUE);

Where printLinehas only color_set, mvprintwand refresh(). Nothing to do with Teleports. Weird

So, I went to the snake function, where the snake gets its next location from the teleport:

    body.push_back(teleports[overlap(next)]->teleportFrom(dir)); //next is a Location object

teleports[overlap(next)]->teleportFrom(dir) , . , (, Teleport - ?), :

    Location l = teleports[overlap(next)]->teleportFrom(dir);
    mvprintw(1, 0, "(%i, %i)", l.x, l.y);
    refresh();

!

, . mvprintw(1, 0, "(%i, %i)", l.x, l.y);, refresh();, , , , , .

, ?

UPDATE: ( / ), 1:

warning: reference to local variable 'other' returned

:

Location& Location::operator = (Location other)
{
    if(this == &other)
        return other;
    x = other.x;
    y = other.y;
    return *this;
}

, ?

+5
4

:
* ( ). , ( ).

Location& Location::operator = (Location const& other)
{
    // Does it really matter if you assign to self?
    x = other.x;
    y = other.y;
    return *this;
}

.

PS. ( , ). , , , . (aI , , , - ).

( ). :

// notice the parameter is passed by value (i.e. a copy).
// So the copy part is aromatically taken care of here.
// So now you just need tom implement the swap() part of the idiom.
Location& Location::operator = (Location other)
{
    this->swap(other);
    return *this;
}

void Location::swap(Location& other)
{
    std::swap(x, other.x);
    std::swap(y, other.y);
}
+8
Location& Location::operator = (Location other)
{
    if(this == &other)
        return other;
    x = other.x;
    y = other.y;
    return *this;
}

. , other? ( , .) , , , , . , "".

return *this . ( , , , .)

( .)

+4

, ? Heisenbug , :

, , , (, )

:

:

, heisenbug, , , . , . , , (, ), , , . - , . ++ .

Make sure that the switches are disconnected - there is no optimization, full debugging information, cleaning up any existing assemblies, rebooting the IDE and recompiling ....

+3
source

First of all, your Location :: operator = should look like this:

Location& Location::operator = (const Location &other)
{
    if(this == &other)
        return *this;
    x = other.x;
    y = other.y;
    return *this;
}

However, this probably does not account for the collapse. Poor stack pointers are not broken here on most architectures (assuming x and y are int).

So this is Mandelbug, not Heisenbug. You have someone else, somewhere corrupting your memory. Good luck.

+1
source

All Articles