Vì mục đích giáo dục, tôi đang viết một tập hợp các phương thức gây ra các ngoại lệ thời gian chạy trong C# để hiểu tất cả các ngoại lệ là gì và nguyên nhân gây ra chúng. Ngay bây giờ, tôi đang làm việc với các chương trình gây ra một số AccessViolationException
.Tại sao không * (int *) 0 = 0 gây ra vi phạm truy cập?
Cách rõ ràng nhất (với tôi) để làm điều này là để viết thư cho một vị trí bộ nhớ được bảo vệ, như thế này:
System.Runtime.InteropServices.Marshal.WriteInt32(IntPtr.Zero, 0);
Cũng như tôi đã hy vọng, điều này đã ném một AccessViolationException
. Tôi muốn làm điều đó một cách chính xác hơn, vì vậy tôi quyết định viết một chương trình với mã không an toàn, và làm (những gì tôi nghĩ là) chính xác điều tương tự bằng cách gán 0
cho con trỏ 0.
unsafe
{
*(int*)0 = 0;
}
Vì lý do khiến tôi khó chịu, điều này ném một số NullReferenceException
. Tôi chơi xung quanh với nó một số và phát hiện ra rằng bằng cách sử dụng *(int*)1
thay vì cũng ném một NullReferenceException
, nhưng nếu bạn sử dụng một số âm, như *(int*)-1
nó sẽ ném một AccessViolationException
.
Điều gì đang xảy ra ở đây? Tại sao *(int*)0 = 0
gây ra một số NullReferenceException
và tại sao nó không gây ra một số AccessViolationException
?
'(int *) 0' là một con trỏ rỗng. Tôi hoàn toàn mong đợi một 'NullReferenceException'. Nếu bạn muốn một 'AccessViolationException', hãy thử một cái gì đó như' (int *) 0x10' (hoặc có thể '0xf0000000'). – cHao
có thể trùng lặp của [Tại sao truy cập bộ nhớ trong không gian địa chỉ thấp nhất (không mặc định) được báo cáo là NullReferenceException bởi .NET?] (Http://stackoverflow.com/questions/7940492/why-is-memory-access-in - thấp nhất-địa chỉ-không gian-không-null-mặc dù-báo cáo-as-n) –