tags:

views:

94

answers:

5

Hi, In a book there is an example about static/non-static objects.

char buf[MAX];
long count=0;
int i=0;
while(i++<=MAX)
    if(buf[i]=='\0') {
        buf[i]='*';
        ++count;
    }
assert(count<=i);

It is said that sometimes the code will write past the end of the buf array into count and make the assertion to fail. And then tells about declaring count as static and solve the problem (note: the author gives this as a bad solution example) Anyway, apart from being a bad example, I cannot figure out how the problem happens, and how it is solved as declaring count as static.

+4  A: 

It's not only a bad solution, it's a non-solution. You can't index over an array's bounds. If you do, you have a non-solvable problem with regard to achieving a correct C++ program.

What you might see on common C++ implementations is that sometimes count is put into the stack directly after buf. So if you over-index and then write, you may modify count and then any assumption on the value of count that is based purely on direct writes to it isn't correct anymore because there is a write to it by that over-index operation.

If you now make it static the variable then is allocated in some other section of the program (usually the .bss for 0-initialized and .data for otherwise initialized data), the count variable on common implementations won't be allocated next to the array anymore and this will cause another incident to happen: Instead of overwriting count you may then be overwriting whatever is then next to the array.

Johannes Schaub - litb
that is ok, but what about count being overwritten? the idea in the section is about variables being overwritten.
paul simmons
+3  A: 

The example counts on a specific layout of the variables in memory, namely that count comes just after buf. By making count static, it gets placed in a different part of memory and something else gets clobbered instead. The problem didn't go away, the symptoms just changed.

Mark Ransom
ah ok, because of wrong 'while..' i gets out of MAX, and writes buf[MAX+1], which is the place of count. am i correct?
paul simmons
Good catch, I did miss that i++ will in fact make `i` get MAX+1.
DarkDust
@DarkDust: it will also make `i` equal to `MAX`, which is just as bad.
Oli Charlesworth
+1  A: 

Johannes' answer is correct.

However, as to why declaring count as static might make it appear to work. When count is declared as non-static, it will typically live immediately after buf[] in memory (on the stack). However, when declared as static, it will not be on the stack, and so will not be corrupted when you write past the end of buf[].

Oli Charlesworth
A: 

I concur, if you exceed an arrays bounds you cause an out of bounds exception. Or in non managed languages like C/C++ you could end up writing/reading into the next lot of memory address, of the memory of my non null terminated string running off into another objects memory wasn't fun.

I am somewhat curious to where is your static object, you declare them all as variables, there is no static object in sight.

The above code should always exceed the array as i is checked against max first, then i is increased which puts i one more than max, giving you an off by 1 error.

JonWillis
A: 

I'd like to read the book, but I imagine it's displaying examples of "Voodoo Programming", where you try random stuff until it stops breaking, and call that a success.

As mentioned elsewhere, all you'd do by declaring it static is move count to a different place, which would mean that the assert might pass. To an inexperienced programmer, that would be enough to submit, at which point you have buffer overrunning code in your production environment.

Of course, I'd expect that "i" would then be overwritten, which would be even worse as it's a control variable for the loop, but I could be wrong about that.

deworde