Share via


fixed (Instrucción, Referencia de C#)

La instrucción fixed evita que el recolector de elementos no utilizados vuelva a ubicar una variable móvil. La instrucción fixed solo se permite en un contexto no seguro. Fixed también se puede utilizar 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 that the following class exists.
    //class Point 
    //{ 
    //    public int x;
    //    public int y; 
    //}

    // Variable 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 that it is not relocated.

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

}

Puede inicializar un puntero mediante una matriz, una cadena, un búfer de tamaño fijo, o la dirección de una variable. En el ejemplo siguiente se muestra el uso de direcciones, matrices y cadenas variables. Para obtener más información sobre los búferes de tamaño fijo, vea Búferes de tamaño fijo (Guía de programación de C#).

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

    // The following two assignments are equivalent. Each assigns the address
    // of the first element in array arr to pointer p.

    // You can initialize a pointer by using an array.
    fixed (double* p = arr) { /*...*/ }

    // You can initialize a pointer by using the address of a variable. 
    fixed (double* p = &arr[0]) { /*...*/ }

    // The following assignment initializes p by using a string.
    fixed (char* p = str) { /*...*/ }

    // The following assignment is not valid, because str[0] is a char, 
    // which is a value, not a variable.
    //fixed (char* p = &str[0]) { /*...*/ } 


    // You can initialize a pointer by using the address of a variable, such
    // as point.x or arr[5].
    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 tipos distintos, simplemente anide instrucciones fixed, como se muestra en el ejemplo siguiente.

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 la Especificación del lenguaje C#. La especificación del lenguaje es la fuente definitiva de la sintaxis y el uso de C#.

Vea también

Referencia

Palabras clave de C#

unsafe (Referencia de C#)

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

Conceptos

Guía de programación de C#

Otros recursos

Referencia de C#

Historial de cambios

Fecha

Historial

Motivo

1 de abril de 2011

Se clarificó qué tipos se pueden usar para inicializar un puntero.

Comentarios de los clientes.