基本上,内存损坏是由覆盖您不应覆盖的内存引起的。我想知道这是否可能与C#中的不安全代码(即不通过调用外部非托管代码)。我看到两种可能的情况:
在这两种情况下,似乎运行时检测并防止潜在的内存损坏发生。因此,是否有可能使用不安全的代码来破坏C#中的内存?作为必然结果,从不安全的代码中捕获AccessViolationExceptions是否安全?
答案 0 :(得分:11)
你错过了Big Bullet:
非常常见,.NET程序中总是存在大量可写内存。包括将元素写入数组的末尾,它很少被炸弹。内存页面边界的内存保护是精细的,Windows上为4096字节。 .NET GC大大提升了这一点,代际堆段是VM的大好处。捕捉AVE是非常不明智的。
可以使用的一些代码:
class Program {
static unsafe void Main(string[] args) {
var arr = new byte[1];
for (int fill = 0; fill < 2 * 1024 - 64; ++fill) {
byte[] dummy = new byte[1024];
}
fixed (byte* p = &arr[0]) {
for (int ix = 1; ; ++ix)
p[ix] = 42;
}
}
}
超过大约1.5兆字节。
答案 1 :(得分:10)
访问指向无效随机存储位置的指针
如果是阅读,则是安全的。如果是写入,如果内存位置恰好有效,则不安全,但您没有拥有它。你将在随机存储位置上涂鸦。
作为必然结果,从不安全的代码中捕获AccessViolationExceptions是否安全?
不,因为该异常告诉您a)您有错误并且b)内存可能已损坏且无法修复。抓住它并尽快拆除这个过程。
答案 2 :(得分:7)
C#中的不安全代码会导致内存损坏吗?
答案是肯定的!,请考虑以下示例执行此操作
int a = 10;
int* p = &a;
*(p+54)= 444;
CLR可能会也可能不会陷入此问题。
并非所有通过坏指针进行的读取或写入都会导致访问冲突,因此访问冲突通常表示通过错误指针发生了多次读取或写入,并且该内存可能已损坏。
答案 3 :(得分:2)
导致AccessViolationException的内存写入没有发生,它没有做任何事情。
但是:它试图写入错误的位置的事实是一个非常强烈的指示,表明之前可能存在无效的写入操作(因为您的代码是错误的),并且这些写入可能指向可写的位置但不应该被改变。