The fixed statement fixes memory in one location. Objects in memory are moved at almost any time. This makes garbage collection possible.
But when we use unsafe pointers to memory addresses, that memory must not be moved. With fixed we can use pointers without interfering with GC.
This program must be compiled with unsafe code allowed. You can set this option in Visual Studio. It introduces the Transform method, which gets a random string
.
string
data.string
data pointed to by the char
* pointer will not be moved.using System; class Program { static void Main() { Console.WriteLine(Transform()); Console.WriteLine(Transform()); Console.WriteLine(Transform()); } unsafe static string Transform() { // Get random string. string value = System.IO.Path.GetRandomFileName(); // Use fixed statement on a char pointer. // ... The pointer now points to memory that won't be moved. fixed (char* pointer = value) { // Add one to each of the characters. for (int i = 0; pointer[i] != '\0'; ++i) { pointer[i]++; } // Return the mutated string. return new string(pointer); } } }61c4eu6h/zt1 ctqqu62e/r2v gbekvhn6/xwq
The fixed modifier describes a buffer of constant size in an unsafe context in a struct
. We use this memory as an array. This can help with performance.
static
struct
reference containing a fixed buffer of integers.Store()
, the program reads and writes values to the fixed buffer using unsafe code and pointers.using System; unsafe struct FixedBufferExample { public fixed int _buffer[1024]; // This is a fixed buffer. } class Program { static FixedBufferExample _fixedBufferExample; // Reference to struct. static void Main() { // Store values in the fixed buffer. // ... The load the values from the fixed buffer. Store(); Load(); } unsafe static void Store() { // Put the fixed buffer in unmovable memory. // ... Then assign some elements. fixed (int* buffer = _fixedBufferExample._buffer) { buffer[0] = 1; buffer[99] = 2; buffer[1023] = 3; } } unsafe static void Load() { // Put in unmovable memory. // ... Then load some values from the memory. fixed (int* buffer = _fixedBufferExample._buffer) { Console.WriteLine(buffer[0]); Console.WriteLine(buffer[99]); Console.WriteLine(buffer[1023]); } } }1 2 3
The fixed buffer eliminates the need of many array bounds checks. But the overhead of changing the memory to an unmovable address often hurts performance.
There is a small cost to using the fixed statement. So it will only help on operations that spend significant amounts of time in unsafe code.
Optimizing with the fixed statement and pointer manipulation is often trial-and-error. It may make C# programs slower due to the transition from movable to fixed memory.
Fixed is used with array elements, integer fields, and any data that is classified as movable—meaning it could be moved in memory during GC. This is a complex optimization.