It's also worth noting that memory-related bugs like the above are always incorrect, but don't necessarily cause a segmentation fault. They are examples of "undefined behaviour", which means the program is allowed to do anything (including crash, or continue executing in some corrupt state). Whether a particular invalid memory access causes a segmentation fault or not usually comes down to a combination of factors around how your program interacts with the specific hardware and OS you are running on. For example, reading from "just" past the end of an array will often appear to succeed and return a value from another part of your program, whereas reading from "further" away from a valid location will more likely crash the program.
In any case, you can't rely on any particular result of running a program with undefined behaviour, essentially "all bets are off" as far as the C language is concerned.
As a bonus example, try running the following code (which contains an invalid array access, but doesn't appear to crash on my PC):
// Save to test.c, then run with
// $ cc -o test test.c
// $ ./test
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
char hello_str[] = "Hello";
char world_str[] = "World";
printf("%c\n", hello_str[6]);
}
and let me know what it does on your system. You can also try changing the '6' to other values outside the range 0-5 and see what other strange results you might get. Can you cause it to segmentation fault?