tags:

views:

93

answers:

6

Here len is at A[10] and i is at A[11]. Is there a way to catch these errors?? I tried compiling with gcc -Wall -W but no warnings are displayed.

int main()
{
  int A[10];
  int i, len;
  len = sizeof(A) / sizeof(0[A]);
  printf("Len = %d\n",len);
  for(i = 0; i < len; ++i){
    A[i] = i*19%7;
  }
  A[i] = 5;
  A[i + 1] = 6;
  printf("Len = %d i = %d\n",len,i);
  return 0;
}

Output : Len = 10 Len = 5 i = 6

+7  A: 

You are accessing memory outside the bounds of the array; in C, there is no bounds checking done on array indices.

Accessing memory beyond the end of the array technically results in undefined behavior. This means that there are no guarantees about what happens when you do it. In your example, you end up overwriting the memory occupied by another variable. However, undefined behavior can also cause your application to crash, or worse.

Is there a way to catch these errors?

The compiler can catch some errors like this, but not many. It is often impossible to catch this sort of error at compile-time and report a warning.

Static analysis tools can catch other instances of this sort of error and are usually built to report warnings about code that is likely to cause this sort of error.

James McNellis
I used splint to static analyse the code, but it failed to catch this error.
Inception
@Inception: Often it is impossible to detect this sort of error at compile-time.
James McNellis
A: 

i's location in memory is just past the end of A. That's not guaranteed with every compiler and every architecture, but most probably wouldn't have a reason to do it any other way.

Note that counting from 0 to 9, you have 10 elements.

altie
+2  A: 

C does not generally do bounds-checking, but a number of people have implemented bounds-checking for C. For instance there is a patch for GCC at http://sourceforge.net/projects/boundschecking/. Of course bounds-checking does have some overhead, but it can often be enabled and disabled on a per-file basis.

T Duncan Smith
+1  A: 

The array allocation of A is adjacent in memory to i and len. Remember that when you address via an array, it's exactly like using pointers, and you're walking off the end of the array, bumping into the other stuff you put there.

C by default does not do bounds checking. You're expected to be careful as a programmer; in exchange you get speed and size benefits.

Usually external tools, like lint, will catch the problems via static code analysis. Some libraries, depending on compiler vendor, will add additional padding or memory protection to detect when you've walked off the end.

Lots of interesting, dangerous, and non-portable things reside in memory at "random spots." Most of the house keeping for heap memory allocations occur in memory locations before the one the compiler gives you.

The general rule is that if you didn't allocate or request it, don't mess with it.

Walt Stoneburner
Take a look at this: http://williambader.com/bounds/example.htmlNote that it's for heap managed memory. Take a look at http://www.gimpel.com/ for static code analysis.
Walt Stoneburner
A: 

Array indexing starts from 0. Hence the size of array is equal to one less than the declared value. You are overwriting the memory beyond what is allowed.

These errors may not be reported as warnings but you can use tools like prevent, sparrow, Klockworks or purify to find such "malpractices" if i may call them that.

Praveen S
A: 

The short answer is that local variables are al-located on stack, and indexing is just like *(ptr + index). So it could happen that the room for int y[N] is adjacent to the room for another int x; e.g. x is located after the last y. So, y[N-1] is this last y, while y[N] is the int past the last y, and in this case, by accident, it happens you get x (or whatever in your practical example). But it is absolutely not a sure fact what you can get going past the bounds of an array and so you can't rely on that. Even though undetected, it's a "index out of bound error", and a source of bugs.

ShinTakezou