Por que * (int *) 0 = 0 não causa uma violação de acesso?

Para fins educacionais, estou escrevendo um conjunto de métodos que causam exceções de tempo de execução em C # para entender o que são todas as exceções e o que as causa. No momento, estou mexendo em programas que causam umAccessViolationException.

A maneira mais óbvia (para mim) de fazer isso era gravar em um local de memória protegido, assim:

System.Runtime.InteropServices.Marshal.WriteInt32(IntPtr.Zero, 0);

Assim como eu esperava, isso jogou umAccessViolationException. Como eu queria fazer isso de forma mais concisa, decidi escrever um programa com código não seguro e fazer (o que eu pensava ser) exatamente a mesma coisa atribuindo0 para o ponteiro zero.

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

Por razões que me escapam, isso gera umNullReferenceException. Eu brinquei com ele e descobri que usando*(int*)1 em vez disso também lança umNullReferenceException, mas se você usar um número negativo, como*(int*)-1 lançará umAccessViolationException.

O que está acontecendo aqui? Porque*(int*)0 = 0 causar umaNullReferenceException e por que não causa umAccessViolationException?

questionAnswers(5)

yourAnswerToTheQuestion