fixed-Anweisung (C#-Referenz)

Aktualisiert: April 2011

Die fixed-Anweisung verhindert, dass der Garbage Collector eine bewegliche Variable verschiebt. Die fixed-Anweisung ist nur in einem unsicheren Kontext erlaubt. Fixed kann auch verwendet werden, um Puffer mit fester Größe zu erstellen.

Die fixed-Anweisung legt einen Zeiger auf eine verwaltete Variable fest und "fixiert" diese Variable während der Ausführung der Anweisung. Zeiger auf bewegliche, verwaltete Variablen wären ohne fixed von geringem Nutzen, da Garbage Collection die Variablen auf unvorhersehbare Weise verschieben könnte. Der C#-Compiler erlaubt die Zuweisung von Zeigern auf verwaltete Variablen nur in einer fixed-Anweisung.

unsafe static void TestMethod()
{

    // Assume that the following class exists.
    //class Point 
    //{ 
    //    public int x;
    //    public int y; 
    //}

    // Variable pt is a managed variable, subject to garbage collection.
    Point pt = new Point();

    // Using fixed allows the address of pt members to be taken,
    // and "pins" pt so that it is not relocated.

    fixed (int* p = &pt.x)
    {
        *p = 1;
    }        

}

Sie können einen Zeiger initialisieren, indem Sie ein Array, eine Zeichenfolge, einen Puffer mit fester Größe oder die Adresse einer Variablen verwenden. Das folgende Beispiel veranschaulicht die Verwendung von variablen Adressen, Arrays und Zeichenfolgen. Weitere Informationen über Puffer mit fester Größe finden Sie unter Puffer fester Größe (C#-Programmierhandbuch).

static unsafe void Test2()
{
    Point point = new Point();
    double[] arr = { 0, 1.5, 2.3, 3.4, 4.0, 5.9 };
    string str = "Hello World";

    // The following two assignments are equivalent. Each assigns the address
    // of the first element in array arr to pointer p.

    // You can initialize a pointer by using an array.
    fixed (double* p = arr) { /*...*/ }

    // You can initialize a pointer by using the address of a variable. 
    fixed (double* p = &arr[0]) { /*...*/ }

    // The following assignment initializes p by using a string.
    fixed (char* p = str) { /*...*/ }

    // The following assignment is not valid, because str[0] is a char, 
    // which is a value, not a variable.
    //fixed (char* p = &str[0]) { /*...*/ } 


    // You can initialize a pointer by using the address of a variable, such
    // as point.x or arr[5].
    fixed (int* p1 = &point.x)
    {
        fixed (double* p2 = &arr[5])
        {
            // Do something with p1 and p2.
        }
    }
}

Mehrere Zeiger können initialisiert werden, solange sie denselben Typ aufweisen.

fixed (byte* ps = srcarray, pd = dstarray) {...}

Um Zeiger verschiedener Typen zu initialisieren, verschachteln Sie einfach fixed-Anweisungen, wie im folgenden Beispiel gezeigt.

fixed (int* p1 = &point.x)
{
    fixed (double* p2 = &arr[5])
    {
        // Do something with p1 and p2.
    }
}

Nach der Ausführung des Anweisungscodes können beliebige fixierte Variablen wieder gelöst und für Garbage Collection freigegeben werden. Zeigen Sie daher nicht außerhalb der fixed-Anweisung auf solche Variablen.

Tipp

Zeiger, die in fixed-Anweisungen initialisiert wurden, können nicht geändert werden.

Im nicht sicheren Modus kann Speicher auf dem Stapel belegt werden. Dort unterliegt er nicht Garbage Collection und muss daher nicht fixiert werden. Weitere Informationen finden Sie unter stackalloc.

Beispiel

    class Point
    { 
        public int x, y; 
    }

    class FixedTest2 
    {
        // Unsafe method: takes a pointer to an int.
        unsafe static void SquarePtrParam (int* p) 
        {
            *p *= *p;
        }

        unsafe static void Main() 
        {
            Point pt = new Point();
            pt.x = 5;
            pt.y = 6;
            // Pin pt in place:
            fixed (int* p = &pt.x) 
            {
                SquarePtrParam (p);
            }
            // pt now unpinned.
            Console.WriteLine ("{0} {1}", pt.x, pt.y);
        }
    }
    /*
    Output:
    25 6
     */

C#-Programmiersprachenspezifikation

Weitere Informationen finden Sie in der C#-Sprachspezifikation. Die Sprachspezifikation ist die verbindliche Quelle für die Syntax und Verwendung von C#.

Siehe auch

Referenz

C#-Schlüsselwörter

unsafe (C#-Referenz)

Puffer fester Größe (C#-Programmierhandbuch)

Konzepte

C#-Programmierhandbuch

Weitere Ressourcen

C#-Referenz

Änderungsprotokoll

Datum

Versionsgeschichte

Grund

April 2011

Erläutert, welche Typen verwendet werden können, um einen Zeiger zu initialisieren.

Kundenfeedback.