Почему этот небезопасный код вызывает исключение NullReferenceException?

Я играл с небезопасным кодом для проблемы на Code Golf, и нашел то, что не могу объяснить. Этот код:

unsafe
{
    int i = *(int*)0;
}

аварийно завершает работу с нарушением прав доступа (Segfault), но этот код:

unsafe
{
    *(int*)0=0;
}

вызывает исключение NullReferenceException. Мне кажется, что первый выполняет чтение, а второй - запись. Исключение говорит мне, что что-то где-то в CLR перехватывает запись и останавливает ее до того, как ОС завершит процесс. Почему это происходит при записи, а не при чтении? Если я сделаю значение указателя достаточно большим, при записи произойдет сбой. Означает ли это, что существует блок памяти, который, как известно CLR, зарезервирован и даже не будет пытаться писать в него? Почему тогда это позволяет мне попытаться прочитать из этого блока? Я что-то неправильно понимаю?

Edit:

Достаточно интересно: System.Runtime.InteropServices.Marshal.WriteInt32 (IntPtr.Zero, 0); Дает мне нарушение доступа, а не NullReference .

12
задан Community 13 April 2017 в 12:38
поделиться