System.AccessViolationException 类
本文提供了此 API 参考文档的补充说明。
如果非托管代码或不安全代码尝试对尚未分配的或不具有访问权限的内存进行读操作或写操作,就会发生访问冲突。 这通常是因为指针具有错误的值。 并非所有通过无效指针的读或写操作都会导致访问冲突,所以访问冲突通常指示已经通过无效指针进行多次读或写操作,并且内存内容可能已损坏。 因此,访问冲突几乎总是指示严重的编程错误。 AccessViolationException 明确表示这些严重错误。
在完全由可验证托管代码组成的程序中,所有引用要么是有效要么是 null,不可能发生访问冲突。 尝试在可验证代码中引用空引用的任何操作都会引发 NullReferenceException 异常。 仅当可验证的托管代码与非托管代码或不安全的托管代码交互时,才会发生 AccessViolationException。
排查 AccessViolationException 异常
只有在不安全的托管代码中,或者当可验证的托管代码与非托管代码交互时,才会发生 AccessViolationException 异常:
- 根据平台不同,不安全的托管代码中发生的访问冲突可以表示为 NullReferenceException 异常或 AccessViolationException 异常。
- 非托管代码中向托管代码显示的访问冲突始终包装在 AccessViolationException 异常中。
在任一情况下,都可以确定 AccessViolationException 异常的原因并加以更正,如下所示:
确保你尝试访问的内存已分配。 尝试访问受保护的内存(即访问未分配或进程不拥有的内存)时,总是会引发 AccessViolationException 异常。
自动内存管理是 .NET 运行时提供的服务之一。 如果托管代码提供与非托管代码相同的功能,你可能希望转到托管代码来使用此功能。 有关详细信息,请参阅 Automatic Memory Management。
确保你尝试访问的内存未损坏。 如果多次读或写操作时都遇到无效指针,则内存可能已损坏。 在预定义缓冲区之外读取或写入地址时,通常会发生这种情况。
AccessViolationException 和 try/catch 块
如果异常发生在运行时保留的内存之外,则 .NET 运行时引发的 AccessViolationException 异常不由结构化异常处理程序中的 catch
语句进行处理。 若要处理此类 AccessViolationException 异常,请对引发异常的方法应用 HandleProcessCorruptedStateExceptionsAttribute 属性。 此更改不会影响用户代码引发的 AccessViolationException 异常,该异常可继续由 catch
语句捕获。