Почему этот небезопасный код вызывает исключение NullReferenceException? - PullRequest
12 голосов
/ 27 декабря 2011

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

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

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

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

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

Edit:

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

1 Ответ

4 голосов
/ 27 декабря 2011

Первое исключение, конечно, имеет смысл - вы пытаетесь прочитать из памяти адрес 0. Второе немного более интересно.: P В C ++ есть макрос / константа с именем NULL, значение которой равно 0. Он используется для недопустимых адресов указателей - очень похоже на нулевое значение в C # для ссылочных типов.Поскольку ссылки на C # являются внутренними указателями, при попытке чтения / записи с этого адреса возникает исключение NullReferenceException - адрес NULL или 0;на самом деле, адреса от 0 до 64K недопустимы во всех процессах (в Windows), чтобы отлавливать ошибки программиста.Точное исключение или ошибка могут незначительно отличаться в зависимости от аппаратного обеспечения компьютера или версии Windows / .NET Framework, но вы должны получить ошибку с обоими фрагментами кода.

Что касается ошибки при чтении / записи на случайные адреса, тосвязано с изоляцией ОС каждого процесса.Вы не можете возиться с кодом или данными других процессов - по крайней мере, не законно.

...