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.