stała instrukcja — przypinanie zmiennej dla operacji wskaźnika

Instrukcja fixed zapobiega przeniesieniu zmiennej przenoszonej przez moduł odśmiecania pamięci i deklaruje wskaźnik do tej zmiennej. Adres stałej lub przypiętej zmiennej nie zmienia się podczas wykonywania instrukcji. Zadeklarowany wskaźnik można użyć tylko wewnątrz odpowiedniej fixed instrukcji. Zadeklarowany wskaźnik jest odczytany i nie można go modyfikować:

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.

Uwaga

Instrukcję fixed można używać tylko w niebezpiecznymkontekście. Kod zawierający niebezpieczne bloki należy skompilować za pomocą opcji kompilatora AllowUnsafeBlocks .

Można zainicjować zadeklarowany wskaźnik w następujący sposób:

  • W przypadku tablicy, jak pokazano na początku tego artykułu. Zainicjowany wskaźnik zawiera adres pierwszego elementu tablicy.

  • Przy użyciu adresu zmiennej. Użyj operatora address-of&, jak pokazano w poniższym przykładzie:

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

    Pola obiektów to kolejny przykład zmiennych, które można przypiąć.

    Gdy zainicjowany wskaźnik zawiera adres pola obiektu lub elementu tablicy, fixed instrukcja gwarantuje, że moduł odśmiecania pamięci nie przenosi ani nie usuwa zawierającego wystąpienia obiektu podczas wykonywania treści instrukcji.

  • Wystąpienie typu implementujące metodę o nazwie GetPinnableReference. Ta metoda musi zwracać zmienną reftypu niezarządzanego. Typy System.Span<T> platformy .NET i System.ReadOnlySpan<T> używają tego wzorca. Możesz przypiąć wystąpienia, jak pokazano w poniższym przykładzie:

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

    Aby uzyskać więcej informacji, zobacz dokumentację interfejsu Span<T>.GetPinnableReference() API.

  • W przypadku ciągu, jak pokazano w poniższym przykładzie:

    unsafe
    {
        var message = "Hello!";
        fixed (char* p = message)
        {
            Console.WriteLine(*p);  // output: H
        }
    }
    
  • Z buforem o stałym rozmiarze.

Pamięć można przydzielić na stosie, gdzie nie podlega wyrzucaniu pamięci i dlatego nie musi być przypięta. W tym celu użyj stackalloc wyrażenia .

Możesz również użyć słowa kluczowego fixed, aby zadeklarować bufor o stałym rozmiarze.

specyfikacja języka C#

Aby uzyskać więcej informacji, zobacz następujące sekcje specyfikacji języka C#:

Zobacz też