Вмешалась ОС? Но если так, то почему?
Потому что классическая ошибка - использование неинициализированного указателя. Ты обьявил a указателем на целое, но не присвоил ему никакого значения (через malloc(), calloc() или функции, возвращающие указатель). Обьявленная переменная была выделена в куче и получила какое-то мусорное значение,
доступное твоей программе (вполне может быть указатель на часть кода, например, на ядро, на общие функции). Ты его прочитал.
При попытке записать по данному адресу поймал SIGSEGV, потому что данный адрес твоей программе по записи недоступен. Все, как должно быть.
могу ли я указателю дать ссылку на конкретную ячейку в памяти?
Теоретически можешь, но практически ось тебе сразу выдаст SIGSEGV, потому что писать ты можешь только в те области памяти, которые тебе доступны по записи.
warning: initialization of 'int *' from 'int' makes pointer from integer without a cast
Ну правильно говорит - инициализация делается без приведения типа. Такой финт ушами часто делают со строками - по умолчанию выставляя там указатель на NULL (что обычно означает, что строке еще не выделялась память), напрмер
char *str = (char *) NULL;