2

In Java, we get a beautiful exception when attempting to access and array out of bounds, but in C that's not the case:

#include <stdio.h>

int main() {
    int x[10] = {1,2,3}; // After the third index, I know that the rest are 0.
    int i = 0;
    while (i<99) { // Here I exceed the size of the array, 
        printf("%d",x[i]); // printing non-existent indexes.
        i++;
    }
    return 0;
}

And the output is:

12300000001021473443840268687241986531780216078041842686812-12686816199941806157
0338438-2199933010019993299657804184019993359001214734438441990611-819265930944-
8192925345321-122881852697619690479012147344384268694020027537742147344384145346
587600214734438400102686884-819226869482003047601567625672026869562002753732-120
02706633004199040214734438402020893505321130682200320201752380100000243875924666
4687366080-21479789413447414207980
Process returned 1 (0x1)   execution time : 0.719 s
Press any key to continue.

Technically, what exactly happened? It's not exactly an "int size overflow", right?

Shafik Yaghmour
  • 154,301
  • 39
  • 440
  • 740
Ericson Willians
  • 7,606
  • 11
  • 63
  • 114

5 Answers5

5

In C Accessing outside the bounds of the array is undefined behavior and the result is unpredictable, it could appear to work correctly, it could seg-fault, etc... The draft C99 standard in Annex J.2 Undefined behavior and lists the following bullet:

An array subscript is out of range, even if an object is apparently accessible with the given subscript (as in the lvalue expression a[1][7] given the declaration int a[4][5]) (6.5.6).

section 6.5.6 paragraph 8, which is normative gives the details.

On the other hand the Java Language Specification section 10.4 makes accessing an array out of bounds an exception:

All array accesses are checked at run time; an attempt to use an index that is less than zero or greater than or equal to the length of the array causes an ArrayIndexOutOfBoundsException to be thrown.

Java and C have different design philosophies. Java goes out of it's way to avoid undefined behavior while C and C++ give latitude to the implementation. A few good articles on this:

Community
  • 1
  • 1
Shafik Yaghmour
  • 154,301
  • 39
  • 440
  • 740
1

Just to add to what Shafik has already said:

Technically, what exactly happened? It's not exactly an "int size overflow", right?

The array is occupying 10 * sizeof(int) bytes of memory. When you're printing array values at an index beyond this size boundary, you're actually accessing parts of memory that have not been allocated for the array. It could be anything. It could be other variable's values; it could be instructions; it could be protected memory that you have no business accessing.

Eugene S
  • 3,092
  • 18
  • 34
1

This is not an int size overflow but overflow in memory access. When you declare x[10] in memory it will allocate address and store 0 for 10 times:

x[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}

As you declare:

x[10] = {1, 2, 3}

it is assigned as {1, 2, 3, 0, 0, 0, 0 , 0, 0 , 0} But you are printing beyond allocated memory so there can be anything stored which is not in hand of your program.

I ran your program and also printed the addresses and values of x[i]s and I can see addresses and values like:

x[0] =  0x7fff4b1b6290:  1
x[1] =  0x7fff4b1b6294:  2
x[2] =  0x7fff4b1b6298:  3
x[3] =  0x7fff4b1b629c:  0
x[4] =  0x7fff4b1b629c:  0
x[5] =  0x7fff4b1b62a0:  0
x[6] =  0x7fff4b1b62a4:  0
x[7] =  0x7fff4b1b62a8:  0
x[8] =  0x7fff4b1b62ac:  0
x[9] =  0x7fff4b1b62b0:  0
x[10] =  0x7fff4b1b62b4: 0
x[11] =  0x7fff4b1b62b8: 11
x[12] =  0x7fff4b1b62bc: 293
x[13] =  0x7fff4b1b62c0: 0
x[14] =  0x7fff4b1b62c4: 0
x[15] =  0x7fff4b1b62c8: 212348189

So you can see till x[9] you are getting right output but after that it will just print the value at the next address and that is random values.

Shafik Yaghmour
  • 154,301
  • 39
  • 440
  • 740
sutirtha
  • 375
  • 3
  • 21
0

In computer programming, bounds checking is any method of detecting whether a variable is within some bounds before it is used. It is usually used to ensure that a number fits into a given type (range checking), or that a variable being used as an array index is within the bounds of the array (index checking). A failed bounds check usually results in the generation of some sort of exception signal.

Refer: http://lelanthran.com/deranged/?p=182

user596031
  • 26
  • 4
0

The people designing C wanted the language as fast and flexible as possible, so the runtime does just what the programmer said, even if its destructive. In Java, the designers protect the programmer from doing something stupid, so every time you access an array it first checks to see if the access is within bounds.

One approach is not necessarily better than another, but each approach is better at doing different things.

sj0h
  • 902
  • 4
  • 4