В образовательных целях я пишу набор методов, которые вызывают исключения во время выполнения на С#, чтобы понять, что все исключения и что их вызывает. Прямо сейчас, я занимаюсь программами, которые вызывают AccessViolationException
.
Самый очевидный способ (для меня) - записать в защищенную память, например:
System.Runtime.InteropServices.Marshal.WriteInt32(IntPtr.Zero, 0);
Как я и надеялся, это бросило AccessViolationException
. Я хотел сделать это более сжато, поэтому решил написать программу с небезопасным кодом и сделать то, что я думал, точно так же, назначив 0
нулевому указателю.
unsafe
{
*(int*)0 = 0;
}
По причинам, которые ускользают от меня, это вызывает a NullReferenceException
. Я немного поиграл с ним, и выяснил, что вместо *(int*)1
вместо *(int*)1
вызывается NullReferenceException
, но если вы используете отрицательное число, например *(int*)-1
, оно выдает AccessViolationException
.
Что здесь происходит? Почему *(int*)0 = 0
вызывает NullReferenceException
, и почему он не вызывает AccessViolationException
?