pevný příkaz – připnutí proměnné pro operace ukazatele

Příkaz fixed zabraňuje uvolnění paměti, aby přemísťoval přesunoutelnou proměnnou a deklaruje ukazatel na danou proměnnou. Adresa pevné nebo připnuté proměnné se během provádění příkazu nezmění. Deklarovaný ukazatel můžete použít pouze uvnitř odpovídajícího fixed příkazu. Deklarovaný ukazatel je jen pro čtení a nelze ho upravit:

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.

Poznámka:

Příkaz můžete použít fixed pouze v nebezpečném kontextu. Kód, který obsahuje nebezpečné bloky, musí být zkompilován s možností kompilátoru AllowUnsafeBlocks .

Deklarovaný ukazatel můžete inicializovat následujícím způsobem:

  • S polem, jak ukazuje příklad na začátku tohoto článku. Inicializovaný ukazatel obsahuje adresu prvního prvku pole.

  • S adresou proměnné. Použijte operátor address-of&, jak ukazuje následující příklad:

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

    Pole objektů jsou dalším příkladem přesunoutelných proměnných, které je možné připnout.

    Pokud inicializovaný ukazatel obsahuje adresu pole objektu nebo prvku pole, příkaz zaručuje, fixed že uvolňování paměti nepřemístí nebo nezlikviduje obsahující instanci objektu během provádění těla příkazu.

  • S instancí typu, která implementuje metodu s názvem GetPinnableReference. Tato metoda musí vrátit proměnnou refnespravovaného typu. Typy System.Span<T> .NET a System.ReadOnlySpan<T> použití tohoto vzoru. Můžete připnout instance rozsahu, jak ukazuje následující příklad:

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

    Další informace najdete v referenčních informacích k Span<T>.GetPinnableReference() rozhraní API.

  • S řetězcem, jak ukazuje následující příklad:

    unsafe
    {
        var message = "Hello!";
        fixed (char* p = message)
        {
            Console.WriteLine(*p);  // output: H
        }
    }
    
  • S vyrovnávací pamětí s pevnou velikostí.

Můžete přidělit paměť v zásobníku, kde není předmětem uvolňování paměti, a proto není nutné připnout. K tomu použijte stackalloc výraz.

Klíčové slovo můžete použít fixed také k deklaraci vyrovnávací paměti s pevnou velikostí.

specifikace jazyka C#

Další informace najdete v následujících částech specifikace jazyka C#:

Viz také