I have a simple for-loop in C++ and the initialization statement is:
for (int n = 0; n < this->fileLines.size(); n++) {
For some crazy reason, the value of n is being set not to 0 but to 249758, which causes the for-loop to evaluate wrong.
Any ideas why this is initializing wrong (i.e., not to 0)?
I think you need to verify after the for loop what the value of n is, I don't see any way this could non-0. Check the value at the start of the switch. Your breakpoint may have interrupted before n was actually set.
Have you tried sticking
std::cerr<<n<<std::endl;
inside of the for loop? This seems a more direct way of observing the value during the running of the program to verify whether or not it is doing what you think, and optimization will not give you problems with this output.
Perhaps your program is multithreaded and someone is inappropriately writing to that memory location?
Related
If we initialize array with 4 elements, for example:
int array[4];
Can we assign values like this because it is also taking 4 values:
for(int i=5;i<9;i++){
cin>>array[i];
}
Out-of-bounds access on an array has undefined behaviour, which is another way of saying "unintended consequences":
int a[4];
int b[4];
for(int i=5;i<9;i++){
a[i] = i;
}
In a debugger watch what it's doing and in particular watch what happens to b.
This may or may not crash, but it's still broken code. C++ will not always alert you to such situations, it's your responsibility as a developer to be aware of what's allowed and not allowed when accessing certain structures.
Accessing an array out of bounds doesn't always cause a crash, but it is always problematic. Try with i = 999999 or i = -9 and see what happens.
The problem with undefined behaviour is that it may appear to be working but these unintended consequences eventually catch up with you. This makes debugging your code very difficult as this out-of-bounds write may stomp a variable that you need somewhere else minutes or hours after the initial mistake, and then your program crashes. Those sorts of bugs are the most infuriating to fix since the time between the cause and effect is extremely long.
It's the same as how throwing lit matches in the garbage may not cause a fire every time but when it does cause a fire you may not notice until it's too late. In C++ you must be extremely vigilant about not introducing undefined behaviour into your code.
You are mixing up two constructs - the logic used to iterate in a loop and the indexing of an array.
You may use
for(int i=5;i<9;i++){
...
}
to run the loop four times. However, you many not use those values of i to access the array. The array index has to be offset appropriately so it is valid.
for(int i=5;i<9;i++){
int index = i - 5;
std::cin >> array[index];
}
No, you get an array with 4 slots. Those slots are
array[0]
array[1]
array[2]
array[3]
So your code is incorrect. It might seem to work, but its still wrong due to whats called Undefined Behavior, next week it might fail
Note. You are better off using std::vector in c++
can we allocate value like this because it is also taking 4 values:
for(int i=5;i<9;i++){
cin>>array[i];
No, we can't. Since the size of the array is 4, the only indices that can be accessed are 0,1,2 and 3. Accessing any other index will have undefined behaviour.
try to run it in any online compiler it is working.
The behaviour is undefined. Possible behaviours include, none of which are guaranteed:
- working
- not working
- random output
- non-random output
- the expected output
- unexpected output
- no output
- any output
- crashing at random
- crashing always
- not crashing
- corruption of data
- different behaviour, when executed on another system
- , when compiled with another compiler
- , on tuesday
- , only when you are not looking
- same behaviour in all of the above cases
- anything else within the power of the computer (hopefully limited by the OS)
been looking around some C++ and noticed this in a few classes, intellisense obviously threw up an error for it but this code had previously worked. Not asking for a fix just asking how it would have worked.
for(int i = 0; i < PACKAGE_MAX; i++)
m_Package.push_back(&m_PrePackage[i]);
for(i = 0; i < PACKAGEPAIR_MAX; i++)
m_PackagePair.push_back(&m_PrePackagePair[i]);
without them being nested the next statement carries over the declared i. And this continues for a few for loops. Is this an old .net method?
Surely after a few loops even though it wants to start when i = 0 it would end up jumping from 0 to 6 on the final for loop statement, same for the 2nd being in increments of 2. Might have been designed like that but this is just me reading around some old sources.
It used to be that Microsoft's compiler allowed variables in the for loop's initializer to stay in scope past the for loop.
Here's a link to a compiler flag describing the behaviour: https://msdn.microsoft.com/en-us/library/84wcsx8x.aspx
Let's consider following loop in C++, where A is vector or other container using .size():
for(int n=0; n < A.size(); ++n)
cout << A[n];
I think it is equivalent to the loop below (at least in this case, if it is not really absolutely equivalent, can you help me to figure out why? I cannot find a counter-example to that)
for(int n=-1; ++n < A.size(); )
cout << A[n];
Is using first loop somehow better than second one? I see people using first loop everywhere, but never saw a second one. Why no one do this like in second example? Are there some counter-indication to not do this?
In both cases, value of n is the same when we execute second line of code, also while exiting loop, we have the same value. Can anything go wrong in the second loop?
For me, second one seems even simpler.
The first one is better because it is conventional. The second one will leave future readers scratching their heads and cursing your name.
Starting at minus one and then incrementing by one to get 0 in the conditional is not a great thing.
I doubt very much the code generated will be different (aside from the loading of zero to a register is possibly more optimal than -1, which may need a full 32 bit value, where zero usually has a short form or can be achieved with "subtract register from itself" or "xor register with itself".
Making the code harder to read is no benefit. If the compiler deems that this sort of solution is better for some reason, then let it mess about with the code. It's even possible that you are MISSING some optimisation tricks because you are using an "unusual" pattern.
If you want to remove the third part of the for-loop, may I suggest a more typical approach:
for(int n=0; n < A.size();)
cout << A[n++];
(Note that for 'standard' types such as int, n++ and ++n should be equivalent in any modern compiler)
This one is WTF city.
The below program is crashing after a few thousand loops.
unsigned long int nTurn = 1;
bool quit = false;
int main(){
while(!quit){
doTurn();
++nTurn;
}
}
That's, of course, simplified from my game, but nTurn is at the moment used nowhere but the incrementing of it, and when I comment out the ++nTurn line, the program will reliably loop forever. Shouldn't it run into the millions?
WTF, stackoverflow?
Your problem is elsewhere.
Some other part of the program is reading from a wild pointer that ends up pointing to nTurn, and when this loop changes the value the other code acts different. Or there's a race condition, and the increment makes this loop take just a tiny bit longer so the race-y thing doesn't cause trouble. There are an infinite number of things you could have wrong elsewhere.
Can you run your program under valgrind? Some errors it won't find, but a lot it will.
may sound silly, but, if I were looking at this, I'd perhaps output the nTurn var and see if it were always crashing out on the value. then, perhaps initialize nTurn to that & see if that also causes it. you could always put this into debug and see what is happening with various registers and so forth. did you try different compilers ?
I'd use a debugger to catch the fault and see the value of nTurn. Or if you have core dump from the crash load it into the debugger to see the var values at the crash time.
One more point, could the problem be when nTurn wraps round and goes to zero?
++nTurn can't be the source of the crash directly. You may have some sort of buffer overflow causing the memory for the nTurn variable to be accessed by pointer arithmetic when it shouldn't be. That would cause weird behavior when combined with the incrementing.
I have a class with the only constructor like this:
IntroScreen::IntroScreen(Game *game) :
View(game), counter(0.0f), message(-1), continueAlpha(255),
continueVisible(false), screenAlpha(255), fadeIn(false), fadeOut(false)
{
}
And somewhere in a method I have this if-statement
if (counter > 10.0f)
And Valgrind says for that line:
Conditional jump or move depends on uninitialised value(s)
But I initialized it in my initializer list! And I think I believe Valgrind. Because, sometimes everything goes correct and sometimes nothing happens.... So, maybe counter gets a wrong value and so it takes long until the counter reaches 10.
I already check my code where I use counter for some errors. But I think you can't "un-initialize a value" with a C++ statement...
These are ALL the lines (except in the initializer list) where I use counter:
counter += speed;
counter = 20.0f;
counter += game->getSpeedFactor();
if (counter >= 15.f)
counter = 15.f;
if (counter > 10.0f)
Valgrind gives the same output for screenAlpha.
Both variables are private and I have no friend classes....
So, what is going on? What the problem could be?
Edit:
I printed the value out:
In the constructor, it was correnct: 0
In my method, it was rubbish. It prited random values like:
-97298.8...
-106542.2...
The print statement is the first line of the method where all assignments to counter are in.
Second Edit:
Can this be the problem!!??
In my Game class, I initialize that IntroScreen like this:
Game::Game() : /* Some other stuff .... */ , view(new IntroScreen(this))`
{}
view is here a pointer to an abstract super-type of IntroScreen called View.
Did you accidentally shadow counter with a local variable that's uninitialized?
Otherwise, it's possible that valgrind is mid-diagnosing this in an object that was already deleted (using sentry values perhaps).
Or valgrind could just be wrong.
Not enough code to reproduce problem.
Generic SO / developer forum advice:
Do provide a minimal code snippet reproducing the problem.
Quite often (about 85% of all cases in my experience) the process of reducing the code snippet already uncovers the bug for you.
Edit: Your addition still doesn't give a compilable example of your problem, but enough information at least to identify then problem - or, at least, one of them:
Game::Game() : /* Some other stuff .... */ , view(new IntroScreen(this))`
{}
I am not sure whether a new() call is even legal in an initializer list. But I am sure that you do not have a fully initialized this at this point, so chances are your IntroScreen constructor does bogus things.
I found it:
getSpeedFactor() returns only the first time I call it a complete wrong number because of time-functions like gettimeofday(). The start value (to time how long it took to update the game) is set initialized to zero and the stop value is micros of the day: which gives a time of the whole day instead of the update time. Once the game loop ran once, the wrong value is corrected (because of the start value gets assigned). But the first time the game-logic was executed, I used getSpeedFactor() to assign counter, so that way counter get a value of -10000...
Thanks all.
Off the top of my head, you may need to define private default and copy constructors that have proper initializers. Haven't used valgrind, but it's a common thing to forget to do.
Just add a debugging printf statement or equivalent, if you have doubts. But I would not believe Valgrind this time.
BTW: delete does not "un-initliase" a value. It deletes object, but the pointer still points to that memory location — it does have a value.