-1

I've been trying this simple code and two-dimensional arrays in C there do not understand why my program does not fail.

It is assumed that the indices are out of range?

#include <stdio.h>
#include <stdlib.h>
#define row 20
#define cols 20

int main(int argc, char *argv[]) 
{
    int x,y;
    int array[row][cols];       

    int cc = array[40][40];

   return 0;
}

regards

GMs
  • 47
  • 5

1 Answers1

5

C is one step up from assembly and machine code. It does no bounds checking for you. Arrays and strings (which are also arrays) do not know how long they are or how much memory was allocated to them. They just point at a starting spot in memory.

Instead walking outside of memory bounds is undefined behavior which is C's way of saying "that's an error, but I don't have to tell you". Checking array[40][40] will give you whatever garbage was in that memory location. It's known as a buffer overflow. array[0][0] will also give you garbage since the array was never initialized and C does not do that for you.

...but the operating system might. This is known as memory protection. Operating systems generally will not allow programs to access memory they were not allocated and their protections are getting better and better. However, memory allocation is not fine grained. The operating system does not know you allocated a 20 by 20 integer array, it just gives your program a hunk of memory to work with, probably larger than it asked for, and leaves the program to slice it up as appropriate.

There are various tools to help you with C's laxidasical attitude. The most important is Valgrind, a memory checker which will do bounds checks and a whole lot more. Here's a tutorial on it. I cannot recommend it enough. It can be a bit obscure, but it will tell you why your program is quietly not working and trace the problem back to its source.

Many C compilers also do not have warnings on by default. Most command line compilers respond to -Wall, but those are not all the warnings (this is not the first time C will lie to you). Some use -Weverything or --pendantic. Some compilers will do bounds checks for you for statically initialized things like int array[20][20]. For example, running clang -Wall (clang is the default C compiler on OS X)...

test.c:11:14: warning: array index 40 is past the end of the array (which contains 20 elements)
      [-Warray-bounds]
    int cc = array[40][40];
             ^         ~~
test.c:9:5: note: array 'array' declared here
    int array[row][cols];       
    ^

While it's useful to learn standard C, its not a very good way to get things done. Once you have a taste for the problems of standard C, I'd suggest looking at a 3rd party library to improve C. Gnome Lib is a good one.

Schwern
  • 153,029
  • 25
  • 195
  • 336
  • Attempts to modify out of bound memory is more likely to fail. The hardware is more likely to catch the write access, and if it doesn't, but corrupts a critical pointer or count, the program may do something between crash and appear to run just fine. An unstable condition that results in sudden crashes "when it worked just fine yesterday". – Gilbert Jun 01 '16 at 00:16
  • @Gilbert: Most hardware will not detect any such accesses reliably or behave in a specific way. C is used much more on non-PC hardware than on PCs. – too honest for this site Jun 01 '16 at 00:49
  • On most systems which are programmed in C heavy-weight libraries or even the standard library are not available. – too honest for this site Jun 01 '16 at 00:51