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ěnnouref
nespravované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#: