fixed-Anweisung: Anheften einer Variablen für Zeigervorgänge

Die fixed-Anweisung verhindert, dass der Garbage Collector eine bewegliche Variable verschiebt, und deklariert einen Zeiger auf diese Variable. Die Adresse einer festen oder angehefteten Variablen ändert sich für die Dauer der Anweisung nicht. Sie können den deklarierten Zeiger nur innerhalb der entsprechenden fixed-Anweisung verwenden. Der deklarierte Zeiger ist schreibgeschützt und kann nicht geändert werden.

unsafe
{
    byte[] bytes = [1, 2, 3];
    fixed (byte* pointerToFirst = bytes)
    {
        Console.WriteLine($"The address of the first array element: {(long)pointerToFirst:X}.");
        Console.WriteLine($"The value of the first array element: {*pointerToFirst}.");
    }
}
// Output is similar to:
// The address of the first array element: 2173F80B5C8.
// The value of the first array element: 1.

Hinweis

Sie können die fixed-Anweisung nur in einem unsicheren Kontext verwenden. Code, in dem unsichere Blöcke enthalten sind, muss mit der Compileroption AllowUnsafeBlocks kompiliert werden.

Sie können den deklarierten Zeiger wie folgt initialisieren:

  • Mit einem Array (wie im Beispiel am Anfang des Artikels gezeigt). Der initialisierte Zeiger enthält die Adresse des ersten Arrayelements.

  • Mit der Adresse einer Variablen. Verwenden Sie wie im folgenden Beispiel den address-of-&-Operator:

    unsafe
    {
        int[] numbers = [10, 20, 30];
        fixed (int* toFirst = &numbers[0], toLast = &numbers[^1])
        {
            Console.WriteLine(toLast - toFirst);  // output: 2
        }
    }
    

    Objektfelder sind ein weiteres Beispiel für bewegliche Variablen, die angeheftet werden können.

    Wenn der initialisierte Zeiger die Adresse eines Objektfelds oder eines Arrayelements enthält, garantiert die fixed-Anweisung, dass der Garbage Collector die enthaltende Objektinstanz während der Ausführung des Anweisungstexts nicht verschiebt oder verwirft.

  • Mit der Instanz des Typs, der eine Methode namens GetPinnableReference implementiert. Die Methode muss eine ref-Variable eines nicht verwalteten Typs zurückgeben. Die .NET-Typen System.Span<T> und System.ReadOnlySpan<T> verwenden dieses Muster. Sie können span-Instanzen wie im folgenden Beispiel gezeigt anheften:

    unsafe
    {
        int[] numbers = [10, 20, 30, 40, 50];
        Span<int> interior = numbers.AsSpan()[1..^1];
        fixed (int* p = interior)
        {
            for (int i = 0; i < interior.Length; i++)
            {
                Console.Write(p[i]);  
            }
            // output: 203040
        }
    }
    

    Weitere Informationen finden Sie in der Referenz für die Span<T>.GetPinnableReference()-API.

  • Mit einer Zeichenfolge:

    unsafe
    {
        var message = "Hello!";
        fixed (char* p = message)
        {
            Console.WriteLine(*p);  // output: H
        }
    }
    
  • Mit einem Puffer mit fester Größe.

Sie können dem Stapel Arbeitsspeicher zuordnen, der nicht automatisch bereinigt wird und daher nicht angeheftet werden muss. Hierzu verwenden Sie einen stackalloc-Ausdruck.

Sie können auch das Schlüsselwort fixed verwenden, um Puffer mit fester Größe zu deklarieren.

C#-Sprachspezifikation

Weitere Informationen finden Sie in den folgenden Abschnitten der C#-Sprachspezifikation:

Weitere Informationen