tags:

views:

92

answers:

3

I wrote this code today, just out of experimentation, and I'm trying to figure out the output.

 /*
  * This code in C attempts to exploit insufficient bounds checking
  * to legitimate advantage.
  * 
  * A dynamic structure with the accessibility of an array.
  * Handy for small-time code, but largely unreliable.
  */
 int array[1] = {0};
 int index = 0;

 put(), get();

 main ( )
 {
    put(1); put(10), put(100);
    printf("%6d %5d %5d\n", get(0), get(1), get(2));
 }

 put ( x )
 int x;
 {
    array[index++] = x;
 }

 get ( index )
 int index;
 {
    return array[index];
 }

The output:
1 3 100

+1  A: 

It's undefined behavior, so the only real explanation is "It does some things on one machine and other things on other machines".

Also, what's with the K&R function syntax?

EDIT: The printf guess was wrong. As far as the syntax, read K&R 2nd Edition (the cover has a red ANSI stamp), which uses modern function syntax (among other useful updates).

Matthew Flaschen
Angad
quixoto
@Angad modern C is more commonly written as `int put(int x)`, but both will compile
cobbal
@quixoto Will do. I was under the impression it increased readability. Since I have used a lot more Java, I know little about C conventions.@cobbal I know it will compile. I just didn't know how outdated the multiline function definitions were.
Angad
+2  A: 

There is a problem there, in that you declare 'array' as an array of length 1 but you write 3 values to it. It should be at least 'array[3]'. Without that, you are writing to unallocated memory, so anything could happen.

The reason it outputs '3' there without the fix is that it is outputting the value of the global 'index' variable, which is the next int in memory (in your case - as I said anything could happen). Even though you do overwrite this with your put(10) call, the index value is used in as the index in the assignment and then post-incremented, which will set it back to 2 - it then gets set to 3 at the end of the put(100) call and subsequently output via printf.

sje397
Holy cow, you are right, it IS the index variable. Many thanks!
Angad
Just modified the code to 4 put() calls. It goes from 3 to 4 as you suggested in the second integer it prints.
Angad
A: 

To expand on what has been said, accessing out-of-bounds array members results in undefined behavior. Undefined behavior means that literally anything could happen. There is no way to exploit undefined behavior unless you're deep into esoteric platform-specific hacks. Don't do it.

If you do want a "dynamic array", you'll have to take care of it yourself. If your requirements are simple, you can just malloc and realloc a buffer. If your needs are more complicated, you might want to define a struct that keeps a separate buffer, a size, and a count, and write functions that operate on that struct. If you're just learning, try it both ways.

Finally, your function declaration syntax is valid, but archaic. That form is rarely seen, and virtually unheard of in new code. Declare put as:

int put(int x) {…}

And always declare main as:

int main(int argc, char **argv) {…}

The names of argc and argv aren't important, but the types are. If you forget those parameters, demons could fly out of your nose.

Thom Smith
Matthew Flaschen
Angad
Also, for the above code to not give bad output, I'll simply declare index before the array :)
Angad