Obviously, you can only access memory you allocated upfront.
So what you're doing basically is:
int *p = malloc(10 * sizeof(int));
Here, you allocate memory for 10 int
s.
*(p + 10) = 1;
This can be rewritten as (by removing pointer arithmetic):
p[10] = 1;
Now, you can clearly see that there's no memory for the 10th item. So in theory, your code should crash here already.
However, often, the OS decides to allocate a little more memory or you've allocated a block of memory next to p
(in which case the OS won't intervene, even though your code doesn't work the way you want it to).
Let me give you an example:
char foo[4] = "foo";
char bar[4] = "bar";
Now (in theory, obviously it depends on what your compiler does) if you access the 5th char of foo
, it actually maps to the first char of bar
:
foo[5] = "c";
printf("%s %s\n", foo, bar); /* == foo car */
As I said, this depends on your compiler and I only give you this example because it might help you understand how the OS allocates memory.
One more thing:
The NULL
pointer ((void *)0
) is "protected" and the OS guarantees that it fails when you try to access the contents of that address.