Szukaj…


Uwagi

  • Aby móc użyć unsafe słowa kluczowego w projekcie .Net, musisz zaznaczyć „Zezwalaj na niebezpieczny kod” we właściwościach projektu => kompilacja
  • Korzystanie z niebezpiecznego kodu może poprawić wydajność, jednak odbywa się to kosztem bezpieczeństwa kodu (stąd określenie unsafe ).

Na przykład, gdy używasz pętli for, tablica taka:

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

.NET Framework zapewnia, że nie przekroczysz granic tablicy, IndexOutOfRangeException jeśli indeks przekroczy granice.

Jeśli jednak użyjesz niebezpiecznego kodu, możesz przekroczyć granice tablicy w następujący sposób:

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

Indeks niebezpiecznych tablic

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

Uruchomienie tego kodu tworzy tablicę o długości 3, ale następnie próbuje uzyskać 5. pozycję (indeks 4). Na mojej maszynie wydrukowano 1910457872 , ale zachowanie nie jest zdefiniowane.

Bez unsafe bloku nie można używać wskaźników, a zatem nie można uzyskać dostępu do wartości poza końcem tablicy bez powodowania zgłoszenia wyjątku.

Używanie niebezpiecznych z tablicami

Podczas uzyskiwania dostępu do tablic za pomocą wskaźników nie ma sprawdzania granic, a zatem nie będzie IndexOutOfRangeException żaden IndexOutOfRangeException . Dzięki temu kod jest szybszy.

Przypisywanie wartości do tablicy za pomocą wskaźnika:

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
                }
            }
        }
    }
}

Natomiast bezpiecznym i normalnym odpowiednikiem byłoby:

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

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

Niebezpieczna część będzie na ogół szybsza, a różnica w wydajności może się różnić w zależności od złożoności elementów w tablicy, jak również zastosowanej logiki. Chociaż może być szybszy, należy go używać ostrożnie, ponieważ jest trudniejszy w utrzymaniu i łatwiejszy do złamania.

Używanie niebezpiecznych z łańcuchami

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
Licencjonowany na podstawie CC BY-SA 3.0
Nie związany z Stack Overflow