Поиск…


замечания

  • Чтобы использовать ключевое слово unsafe в проекте .Net, вы должны установить флажок «Разрешить небезопасный код» в Project Properties => Build
  • Использование небезопасного кода может повысить производительность, однако это за счет безопасности кода (отсюда и термин unsafe ).

Например, когда вы используете цикл for для такого массива:

for (int i = 0; i < array.Length; i++)
{
    array[i] = 0;
}

.NET Framework гарантирует, что вы не превысите границы массива, бросая IndexOutOfRangeException если индекс превышает границы.

Однако, если вы используете небезопасный код, вы можете превысить границы массива следующим образом:

unsafe
{
    fixed (int* ptr = array)
    {
        for (int i = 0; i <= array.Length; i++)
        {
            *(ptr+i) = 0;
        }
    }
}

Небезопасный индекс массива

void Main()
{
    unsafe
    {
        int[] a = {1, 2, 3};
        fixed(int* b = a)
        {
            Console.WriteLine(b[4]);
        }
    }
}

Запуск этого кода создает массив длиной 3, но затем пытается получить 5-й элемент (индекс 4). На моей машине это напечатано 1910457872 , но поведение не определено.

Без unsafe блока вы не можете использовать указатели и, следовательно, не можете получать доступ к значениям за конец массива, не вызывая исключения.

Использование небезопасных массивов

При доступе к массивам с помощью указателей проверка границ не выполняется, поэтому исключение IndexOutOfRangeException не будет выбрано. Это делает код быстрее.

Присвоение значений массиву с указателем:

class Program
{
    static void Main(string[] args)
    {
        unsafe
        {
            int[] array = new int[1000]; 
            fixed (int* ptr = array)
            {
                for (int i = 0; i < array.Length; i++)
                {
                    *(ptr+i) = i; //assigning the value with the pointer
                }
            }
        }
    }
}

В то время как безопасный и нормальный аналог будет:

class Program
{
    static void Main(string[] args)
    {            
        int[] array = new int[1000]; 

        for (int i = 0; i < array.Length; i++)
        {
            array[i] = i;
        }
    }
}

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

Использование небезопасных строк

var s = "Hello";      // The string referenced by variable 's' is normally immutable, but
                      // since it is memory, we could change it if we can access it in an 
                      // unsafe way.

unsafe                // allows writing to memory; methods on System.String don't allow this
{
  fixed (char* c = s) // get pointer to string originally stored in read only memory
    for (int i = 0; i < s.Length; i++)
      c[i] = 'a';     // change data in memory allocated for original string "Hello"
}
Console.WriteLine(s); // The variable 's' still refers to the same System.String
                      // value in memory, but the contents at that location were 
                      // changed by the unsafe write above.
                      // Displays: "aaaaa"


Modified text is an extract of the original Stack Overflow Documentation
Лицензировано согласно CC BY-SA 3.0
Не связан с Stack Overflow