Подтвердить что ты не робот

Почему буферы с фиксированным размером (массивы) должны быть небезопасными?

Скажем, я хочу иметь тип значения 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];
}

Конечно, второе определение проще. Проблема заключается в небезопасном ключевом слове, который должен предоставляться для фиксированных буферов. Я понимаю, что это реализовано с использованием указателей и, следовательно, небезопасно.

Мой вопрос, почему он должен быть небезопасным? Почему С# не может создавать произвольные массивы постоянной длины и сохранять их как тип значения вместо того, чтобы создавать массив ссылочного типа С# или небезопасные буферы?

4b9b3361

Ответ 1

Потому что "фиксированный буфер" не является реальным массивом. Это настраиваемый тип значения, единственный способ генерировать его на языке С#, который я знаю. 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];
}

В этом примере вы можете произвольно получить доступ к фрейму стека. Стандартный метод переполнения буфера будет доступен для вредоносного кода для исправления адреса возврата функции и принудительного перехода вашего кода в произвольное местоположение.

Да, это совершенно небезопасно.