Para propósitos educativos, estoy escribiendo un conjunto de métodos que causan excepciones de tiempo de ejecución en C# para comprender qué son todas las excepciones y qué las causa. En este momento, estoy jugando con los programas que causan un AccessViolationException
.¿Por qué * (int *) 0 = 0 no causa una infracción de acceso?
La manera más obvia (para mí) para hacer esto era escribir en una posición de memoria protegida, así:
System.Runtime.InteropServices.Marshal.WriteInt32(IntPtr.Zero, 0);
Tal como lo había esperado, esta arrojó una AccessViolationException
. Quería hacerlo de manera más concisa, así que decidí escribir un programa con código inseguro, y hacer (lo que pensé que era) exactamente lo mismo asignando 0
al cero.
unsafe
{
*(int*)0 = 0;
}
Por razones que escapan a mí, esto arroja una NullReferenceException
. Jugué un poco con eso y descubrí que usar *(int*)1
en su lugar también arroja un NullReferenceException
, pero si usa un número negativo, como *(int*)-1
arrojará un AccessViolationException
.
¿Qué está pasando aquí? ¿Por qué *(int*)0 = 0
causa un NullReferenceException
, y por qué no causa un AccessViolationException
?
'(int *) 0' es un puntero nulo. Esperaría una 'NullReferenceException'. Si desea una 'AccessViolationException', intente algo como' (int *) 0x10' (o posiblemente '0xf0000000'). – cHao
posible duplicado de [¿Por qué el acceso a la memoria en el espacio de direcciones más bajo (no nulo, sin embargo) informó como NullReferenceException por .NET?] (Http://stackoverflow.com/questions/7940492/why-is-memory-access-in -the-lowest-address-space-non-null-though-reported-as-n) –