fixed, instruction - épingler une variable pour les opérations de pointeur

L’instruction fixed empêche le récupérateur de mémoire de déplacer une variable déplaçable, et déclare un pointeur vers cette variable. L’adresse d’une variable fixe ou épinglée ne change pas durant l’exécution de l’instruction. Vous pouvez utiliser le pointeur déclaré uniquement à l’intérieur de l’instruction fixed correspondante. Le pointeur déclaré est en lecture seule et ne peut pas être modifié :

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.

Notes

Vous pouvez utiliser l’instruction fixed uniquement dans un contexte non sécurisé. Le code qui contient des blocs unsafe doit être compilé avec l’option de compilateur AllowUnsafeBlocks.

Vous pouvez initialiser le pointeur déclaré comme suit :

  • Avec un tableau, comme le montre l’exemple au début de cet article. Le pointeur initialisé contient l’adresse du premier élément de tableau.

  • Avec l’adresse d’une variable. Utilisez l’opérateur address-of &, comme le montre l’exemple suivant :

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

    Les champs d’objet sont un autre exemple de variables déplaçables qui peuvent être épinglées.

    Lorsque le pointeur initialisé contient l’adresse d’un champ d’objet ou d’un élément de tableau, l’instruction fixed garantit que le récupérateur de mémoire ne déplace pas ou ne supprime pas l’instance d’objet conteneur pendant l’exécution du corps de l’instruction.

  • Avec l’instance du type qui implémente une méthode nommée GetPinnableReference. Cette méthode doit retourner une variable ref d’un type non managé. Les types System.Span<T> et System.ReadOnlySpan<T> de .NET utilisent ce modèle. Vous pouvez épingler des instances span, comme le montre l’exemple suivant :

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

    Pour plus d'informations, consultez la référence d’API Span<T>.GetPinnableReference().

  • Avec une chaîne, comme le montre l’exemple suivant :

    unsafe
    {
        var message = "Hello!";
        fixed (char* p = message)
        {
            Console.WriteLine(*p);  // output: H
        }
    }
    
  • Avec une mémoire tampon de taille fixe.

Vous pouvez allouer de la mémoire à la pile, où elle n’est pas soumise au nettoyage de la mémoire et n’a donc pas besoin d’être épinglée. Pour ce faire, utilisez une expression stackalloc.

Vous pouvez également utiliser le mot clé fixed pour déclarer une mémoire tampon de taille fixe.

spécification du langage C#

Pour plus d’informations, consultez les sections suivantes de la spécification du langage C# :

Voir aussi