Partager via


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

L’instruction fixed empêche le garbage collector 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 pendant l’exécution de l’instruction. Vous pouvez utiliser le pointeur déclaré uniquement à l’intérieur de l’instruction correspondante fixed . 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.

Remarque

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

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

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

  • Avec une adresse d’une variable. Utilisez l’opérateur address-of&, comme l’illustre 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 garbage collector 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 ref variable d’un type non managé. Types .NET System.Span<T> et System.ReadOnlySpan<T> utilisation de ce modèle. Vous pouvez épingler des instances d’étendue, comme l’illustre 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 de l’API Span<T>.GetPinnableReference() .

  • Avec une chaîne, comme l’illustre 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 sur la pile, où elle n’est pas soumise au garbage collection et n’a donc pas besoin d’être épinglée. Pour ce faire, utilisez une stackalloc expression.

Vous pouvez également utiliser le fixed mot clé 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