为什么固定大小的缓冲区(数组)必须是不安全的?

时间:2010-05-21 10:57:44

标签: c# arrays unsafe fixed value-type

假设我想要一个7字节(或3或777)的值类型。

我可以这样定义:

public struct Buffer71
{
    public byte b0;
    public byte b1;
    public byte b2;
    public byte b3;
    public byte b4;
    public byte b5;
    public byte b6;
}

更简单的定义方法是使用固定缓冲区

public struct Buffer72
{
    public unsafe fixed byte bs[7];
}

当然第二个定义更简单。问题在于必须为固定缓冲区提供unsafe关键字。我知道这是使用指针实现的,因此不安全。

我的问题是为什么它必须不安全?为什么C#不能提供任意常量长度数组并将它们保存为值类型而不是使其成为C#引用类型数组或不安全缓冲区?

1 个答案:

答案 0 :(得分:12)

因为“固定缓冲区”不是真正的数组。它是一个自定义值类型,关于用我知道的C#语言生成一个的唯一方法。 CLR无法验证数组的索引是否以安全的方式完成。代码也不可验证。最具代表性的演示:

using System;

class Program {
    static unsafe void Main(string[] args) {
        var buf = new Buffer72();
        Console.WriteLine(buf.bs[8]);
        Console.ReadLine();
    }
}
public struct Buffer72 {
    public unsafe fixed byte bs[7];
}

您可以在此示例中任意访问堆栈帧。标准缓冲区溢出注入技术可用于恶意代码,以修补函数返回地址并强制您的代码跳转到任意位置。

是的,那是非常不安全的。

相关问题