Sök…


Anmärkningar

  • För att kunna använda det unsafe nyckelordet i ett .Net-projekt måste du markera "Tillåt osäker kod" i Projektegenskaper => Bygg
  • Att använda osäkra koder kan förbättra prestandan, men det är på bekostnad av kodesäkerhet (därmed termen unsafe ).

Till exempel, när du använder en för loop, en matris som så:

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

.NET Framework säkerställer att du inte överskrider gränserna för matrisen och kastar ett IndexOutOfRangeException om indexet överskrider gränserna.

Om du använder osäker kod kan du dock överskrida matrisens gränser så:

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

Osäker arrayindex

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

Att köra den här koden skapar en matris med längd 3, men försöker sedan få det femte objektet (index 4). På min maskin skrivs detta ut 1910457872 , men beteendet definieras inte.

Utan det unsafe blocket kan du inte använda pekare och kan därför inte komma åt värden förbi slutet av en matris utan att orsaka att ett undantag kastas.

Använda osäkra med matriser

Vid åtkomst till matriser med pekare finns det ingen gränskontroll och därför kommer ingen IndexOutOfRangeException att kastas. Detta gör koden snabbare.

Tilldela värden till en matris med en pekare:

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

Medan den säkra och normala motsvarigheten skulle vara:

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

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

Den osäkra delen kommer i allmänhet att vara snabbare och skillnaden i prestanda kan variera beroende på komplexiteten hos elementen i matrisen såväl som den logik som tillämpas på var och en. Även om det kan vara snabbare, bör det användas med försiktighet eftersom det är svårare att underhålla och lättare att bryta.

Använda osäkra med strängar

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
Licensierat under CC BY-SA 3.0
Inte anslutet till Stack Overflow