Prevents relocation of a variable by the garbage collector.
fixed ( type* ptr = expr ) statement
where:
The fixed statement is only permitted in an unsafe context.
The fixed statement sets a pointer to a managed variable and "pins" that variable during the execution of statement. Without fixed, pointers to managed variables would be of little use since garbage collection could relocate the variables unpredictably. (In fact, the C# compiler will not allow you to set a pointer to a managed variable except in a fixed statement.)
// assume class Point { public int x, y; } Point pt = new Point(); // pt is a managed variable, subject to g.c. fixed ( int* p = &pt.x ){ // must use fixed to get address of pt.x and *p = 1; // pin pt in place while we use the pointer }
You can initialize a pointer with the address of an array or a string:
fixed (int* p = arr) ... // equivalent to p = &arr[0] fixed (char* p = str) ... // equivalent to p = &str[0]
You can initialize multiple pointers, as long as they are all of the same type:
fixed (byte* ps = srcarray, pd = dstarray) {...}
To initialize pointers of different type, simply nest fixed statements:
fixed (int* p1 = &p.x) fixed (double* p2 = &array[5]) // do something with p1 and p2
Pointers initialized in fixed statements cannot be modified.
After statement is executed, any pinned variables are unpinned and subject to garbage collection, so do not save pointers to those variables outside the fixed statement.
using System; class Point { public int x, y; } class FixedTest { // unsafe method: takes pointer to int unsafe static void SquarePtrParam (int* p) { *p *= *p; } public static void Main() { Point pt = new Point(); pt.x = 5; pt.y = 6; unsafe { // pin pt in place: fixed (int* p = &pt.x) { SquarePtrParam (p); } // pt now unpinned } Console.WriteLine ("{0} {1}", pt.x, pt.y); } }
25 6