C#中的不安全代码会导致内存损坏吗?

Asi*_*sik 9 .net c#

基本上,内存损坏是由覆盖您不应该覆盖的内存引起的.我想知道这是否可能与C#中的不安全代码(即不通过调用外部非托管代码).我看到两种可能的情况:

  • 访问空指针 - >由CLR捕获,抛出NullReferenceException
  • 访问指向无效随机存储器位置的指针 - >由CLR捕获,抛出AccessViolationException

在这两种情况下,似乎运行时检测并防止潜在的内存损坏发生.因此,是否有可能使用不安全的代码来破坏C#中的内存?作为必然结果,从不安全的代码中捕获AccessViolationExceptions是否安全?

Han*_*ant 11

你错过了大子弹:

  • 访问内存而不是获取AccessViolationException.

这是非常常见的,.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;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

超过约1.5兆字节.


usr*_*usr 10

访问指向无效随机存储器位置的指针

如果是阅读,那就安全了.如果它是写入,如果内存位置恰好有效,但您没有拥有它是不安全的.你将在随机存储位置上涂鸦.

作为必然结果,从不安全的代码中捕获AccessViolationExceptions是否安全?

不,因为该异常告诉您a)您有错误并且b)内存可能已损坏且无法修复.抓住它并尽快拆除这个过程.

  • 即使您拥有内存位置,写入也可能损坏内容.不安全的代码可能会在托管对象的顶部,堆数据结构,堆栈帧等上乱涂乱画. (2认同)

Sri*_*vel 7

C#中的不安全代码会导致内存损坏吗?

答案是肯定的!,请考虑以下示例

int a = 10;
int* p = &a;
*(p+54)= 444;
Run Code Online (Sandbox Code Playgroud)

CLR可能会也可能不会陷阱.

并非所有的读取或写入通过坏指针导致访问冲突,所以访问冲突通常表明几个读取或写入操作都通过坏指针发生,并且内存可能已损坏.

来自Accessviolationexception文档