The first example has a wild (not explicitly initialized) pointer. Since it's not an automatic variable, it is set to 0, which clearly is not memory you own. You can see this by printing it out with:
printf("%p\n", p)
As for the second, C99 §6.9.2 actually gives this as an example:
EXAMPLE 2 If at the end of the
translation unit containing
int i[];
the array i still has incomplete type,
the implicit initializer causes it to
have one element, which is set to zero
on program startup.
In general, objects with tentative definition (no initializer) are initialized with 0, which for an array means a 1-element array with element value 0.