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
?