fixed (Instrucción, Referencia de C#)

Actualización: noviembre 2007

La instrucción fixed evita que el recolector de elementos no utilizados vuelva a ubicar una variable móvil. La instrucción fixed sólo se permite en un contexto unsafe. También se puede utilizar Fixed para crear búferes de tamaño fijo.

La instrucción fixed establece un puntero a una variable administrada y "ancla" esa variable durante la ejecución de la instrucción. Sin la instrucción fixed, los punteros a variables administradas móviles serían de poca utilidad, ya que el proceso de recolección de elementos no utilizados podría cambiar la ubicación de las variables de forma impredecible. El compilador de C# sólo permite asignar un puntero a una variable administrada en una instrucción fixed.

unsafe static void TestMethod()
{

    // assume class Point { public int x, y; }
    // pt is a managed variable, subject to garbage collection.
    Point pt = new Point();

    // Using fixed allows the address of pt members to be
    // taken, and "pins" pt so it isn't relocated.

    fixed (int* p = &pt.x)
    {
        *p = 1;
    }        

}

Un puntero se puede inicializar con la dirección de una matriz o de una cadena:

unsafe void Test2()
{
    Point point = new Point();
    double[] arr = { 0, 1.5, 2.3, 3.4, 4.0, 5.9 };
    string str = "Hello World";

    fixed (double* p = arr) { /*...*/ }   // equivalent to p = &arr[0]
    fixed (char* p = str) { /*...*/ }  // equivalent to p = &str[0]

    fixed (int* p1 = &point.x)
    {
        fixed (double* p2 = &arr[5])
        {
            // Do something with p1 and p2.
        }
    }

}

Se pueden inicializar varios punteros a la vez, siempre que sean del mismo tipo:

fixed (byte* ps = srcarray, pd = dstarray) {...}

Para inicializar punteros de diferente tipo, simplemente anide instrucciones fixed:

fixed (int* p1 = &point.x)
{
    fixed (double* p2 = &arr[5])
    {
        // Do something with p1 and p2.
    }
}

Después de ejecutar el código de la instrucción, se desancla cualquier variable anteriormente anclada y queda sujeta al proceso de recolección de elementos no utilizados. Por lo tanto, no se debe apuntar a esas variables desde fuera de la instrucción fixed.

Nota:

Los punteros inicializados en instrucciones fixed no se pueden modificar.

En el modo no seguro (unsafe), se puede asignar memoria a la pila, donde no está sometida a recolección de elementos no utilizados y, por lo tanto, no necesita anclarse. Para obtener más información, vea stackalloc (Referencia de C#).

Ejemplo

class Point
{ 
    public int x, y; 
}

class FixedTest2 
{
    // Unsafe method: takes a pointer to an int.
    unsafe static void SquarePtrParam (int* p) 
    {
        *p *= *p;
    }

    unsafe static void Main() 
    {
        Point pt = new Point();
        pt.x = 5;
        pt.y = 6;
        // Pin pt in place:
        fixed (int* p = &pt.x) 
        {
            SquarePtrParam (p);
        }
        // pt now unpinned
        Console.WriteLine ("{0} {1}", pt.x, pt.y);
    }
}
/*
Output:
25 6
 */

Especificación del lenguaje C#

Para obtener más información, vea las secciones siguientes de Especificación del lenguaje C#.

  • 18.3 Variables fijas y movibles

  • 18.6 La instrucción fixed

Vea también

Conceptos

Guía de programación de C#

Referencia

Palabras clave de C#

unsafe (Referencia de C#)

Búferes de tamaño fijo (Guía de programación de C#)

Otros recursos

Referencia de C#