При объявлении глобального указателя он будет инициализирован нулем, поэтому сгенерированные адреса будут небольшими числами, которые могут или не могут быть доступны для чтения в вашей системе.
При объявлении автоматического указателя его начальное значение, вероятно, будет гораздо интереснее. В этом случае это будет любая библиотека времени выполнения, оставленная в этой точке в стеке до вызова main (), или, возможно, оставшееся значение из сгенерированного компилятором кода установки стекового фрейма. Вероятно, это будет сохраненный указатель стека или указатель кадра, который является допустимым указателем, если используется с небольшими смещениями.
Так или иначе, в неинициализированном указателе что-то есть, и одно значение приводит к ошибке, а другое, на данный момент, в вашей системе - нет.
И это , потому что ошибка сегментации - это механизм ОС, а не язык C.
Ошибка - это основанный на блоках механизм, который выделяет себе и другим программам некоторое количество страниц (каждая из которых составляет несколько K), и он защищает себя и страницы других программ, позволяя вашей программе свободно управлять. Вы должны выйти за пределы контекста блока или попытаться написать страницу только для чтения (даже если она у вас), чтобы создать ошибку. Простого нарушения языкового правила не обязательно достаточно. Операционная система рада позволить вашей программе плохо себя вести и вести себя странно из-за ее диких ссылок, при условии, что она только читает и пишет (или прерывает) сама.