Strange anomaly. What is the reason?

Hello everyone,
generally I avoid asking questions here. Usually I just track the problem and eventually find the bug by myself. But right now, I'm pretty sure I know where bug is and I will find it, but I'm not asking about how to fix a bug.
I'm asking why something is happening.
Let me show you a bit of my code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
//Menu.cpp
//code...
void Menu::PrepareOptions(int& options/*options flags*/)
{
    int pos = 1;//First block will be at first position
    //optionsBlocks is of type std::vector<Block*>
    if( options & OPTION_START )
    {
        optionsBlocks.push_back( new Button(*_win, "Start.png", CHOICE_START, pos++) );
    }
    if ( options & OPTION_RETURN )
    {
        optionsBlocks.push_back( new Button(*_win, "Return.png", CHOICE_RETURN, pos++) );
    }
    if( options & OPTION_HELP )
    {
        optionsBlocks.push_back( new Button(*_win, "Help.png", CHOICE_HELP, pos++) );
    }
    if ( options & OPTION_CREDITS )
    {
        optionsBlocks.push_back( new Button(*_win, "Credits.png", CHOICE_CREDITS, pos++) );
    }
    if ( options & OPTION_OPTIONS )
    {
        optionsBlocks.push_back( new Button(*_win, "Options.png", CHOICE_OPTIONS, pos++) );
    }
    //Logger::Get()->Log("123456789ABCDEFF");
    //If I add this call here, Exit button will be rendered in top left screen(with x=0 and y=0)
    //If I won't, exit will still be pushed back, but it won't have proper position, so it won't be rendered

    if ( options & OPTION_EXIT )
    {

        optionsBlocks.push_back( new Button(*_win, "Exit.png", CHOICE_EXIT, pos++) );
    }
    //Wheter logger will log anything here or not, it does not matter.
}

1
2
3
4
5
6
7
//Logger.hpp
//code...
//logText is of type std::ofstream
void Logger::Log(std::string logText)
{
    log << logText << std::endl;
}


So that's the code. As comments in Menu.hpp explained - currently I have a bug - last button("Exit"), is not rendered, nor present in menu screen(I click everywhere, but it doesn't interact; it's simply not there).
It's okay. I started tracking this bug with logger, and found out interesting thing - if I log 16 chars long or longer string after creating 3rd button(CREDITS), but before creating Exit button, Exit button will indeed be rendered and I can even click on it. It works just good, it just has bad position - it's positioned in upper left corner(so it has x=0 and y=0).


However, if I log anywhere in between these buttons(so e.g. after creating 2nd one but before 3rd, before creating 1st button, or after creating exit button), nothing will happen. Exit will still not be visible nor functioning.

I thought it may be depending on time, but I'm not sure if it works - I used SDL_Delay, and it didn't work. Only logger is making Exit real.

Logger is singleton, and it's not depending nor modifying any external data, except std::ofstream.

If you need some more code please let me know. I just want to understand, why logger is causing this behavior, especially if it's not changing any values, and why it needs exactly 16 characters(without '\0') to make Exit button renderable.
The code you've posted has no obvious flaw.

How big is your project? Is there somewhere you can post everything? Even if it is a zipped archive that could be downloaded and compiled to see the error in action?

As I said, bug isn't the problem. I found the bug. It was really easy to track. Here's the bit of the code with the bug:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
//Button.cpp

//includes...
int Button::totalItems;

Button::Button(Window& win, const char* filepath, int number, int pos)
{
    image = std::move( std::unique_ptr<Texture>(new Texture(filepath, win)));
    filename = filepath;
    choiceNumber = number;
    totalItems++;
    lastTotalItems = totalItems;
    posInQueue = pos;
    CalculatePosition(); // <-- THIS WAS CAUSING BUG! Or should I say, lack of this function :)

}
//code...

void Button::Draw()
{
    if(lastTotalItems != totalItems )
        CalculatePosition();
    //And draw it :) .
    image->Draw(position.x, position.y );
}
//code... 


So, what was wrong : when I created block, I forgot to initialize its position(the code above is the fixed one). Menu is designed with brilliant MatthewRock's Button-placement algorithm, and it positions buttons depending on how many of buttons are in menu. I forgot to calculate their position, so actually every button(except the last one) had its position calculated.

However, I still don't understand the logger thing. The bug was still there, but somehow adding logger call made its position be 0. What could be the cause of this?

PS. I could post my project; It's not *really* big, but it has ~15 headers and .cpp files, and may not be well documented, so you would probably waste much of your time trying to understand what's going on. But if you are willing to explore this problem, then sure, I can deliver source.
Last edited on
You were using whatever garbage happened to be at the memory locations when you didn't initialize the variables. The log call just happened to use that memory for some work and set it to the values you observed. That's all.
That's actually reasonable. Thank you. Btw. does it mean that by changing value of string, I could change position of block?
Topic archived. No new replies allowed.