空引用异常与零指针访问冲突

时间:2014-04-09 11:39:41

标签: c# nullreferenceexception null-pointer

最近我读了一本关于c#的书,并且非常混淆了这样一句话,即当引用指针被取消引用时,空引用异常与本机代码中的访问冲突不同。这个的含义对我来说还不清楚,请不能解释一下,好吗?

2 个答案:

答案 0 :(得分:1)

当您取消引用NullReferenceException的对象引用时,会发生nullnull是CLR上的一个特殊值,表示“无对象”。它意味着空指针。实际上它是一个空指针,但这是一个实现细节。

对于托管代码,AccessViolationException没有意义,因为托管代码中没有指针。不要将概念级别与当前实现混淆。

答案 1 :(得分:1)

在本机代码中,您可以使用指针直接访问内存位置。如果指针是32位,则可以访问大约40亿个虚拟内存位置(2 ^ 32)。但是,并非所有虚拟内存位置都映射到物理内存,而某些位置仅映射为只读(例如代码)。如果本机代码尝试访问无法访问的虚拟内存位置,则会在CPU上出现访问冲突。

因此,当您使用无效指针(读取或写入指针指向的位置)时,会发生访问冲突。保护硬件内存管理器可以通过捕获CPU上的无效访问并引发某种形式的错误情况或异常来帮助您发现这些错误。但是,您也可以使用无效指针来访问可访问的内存位置。即使访问无效,CPU也不会发现它,这可能导致内存损坏和其他难以修复的错误。

本机代码中的常见错误是在使用之前忘记初始化指针。通常,指针将指向地址0(也称为空指针)。捕获此类错误的策略是使虚拟地址空间中的第一页(从地址0开始)不可访问。取消引用无效指针后,您将获得访问冲突。因此,在本机代码中,空指针错误被报告为访问冲突,因为地址0不可访问。

.NET在虚拟机上执行,不提供指针(除非您编写 unsafe 代码)。访问冲突的概念不适用于.NET代码。但是,.NET引用可以是未初始化的(例如null)。取消引用空引用时,虚拟机将抛出NullReferenceException。从概念上讲,这有点类似于如上所述将本机代码空指针错误报告为访问冲突,但概念和机制不同。