Tuesday, July 24, 2012

Fixed Statement in c#

The fixed statement prevents the garbage collector from relocating a movable variable. The fixed statement is only permitted in an unsafe context. Fixed can also be used to create fixed size buffers.

The fixed statement sets a pointer to a managed variable and "pins" that variable during the execution of the statement. Without fixed, pointers to movable managed variables would be of little use since garbage collection could relocate the variables unpredictably. The C# compiler only lets you assign a pointer to a managed variable in a fixed statement.

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

}


You can initialize a pointer with the address of an array or a string:

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

}


You can initialize multiple pointers, as long as they are all of the same type:











fixed (byte* ps = srcarray, pd = dstarray) {...}
fixed (int* p1 = &point.x)
{
fixed (double* p2 = &arr[5])
{
// Do something with p1 and p2.
}
}
After the code in the statement is executed, any pinned variables are unpinned and subject to garbage collection. Therefore, do not point to those variables outside the fixed statement.

In unsafe mode, you can allocate memory on the stack, where it is not subject to garbage collection and therefore does not need to be pinned. For more information, see stackalloc.(MSDN LINK)

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
*/

Source :MSDN

No comments:

Post a Comment