C# > Interop and Unsafe Code > Unsafe Code > Fixed Keyword
Using the 'fixed' keyword to pin memory for direct access
This snippet demonstrates how to use the fixed
keyword in C# to pin an array in memory, allowing for direct pointer manipulation via unsafe code. This is crucial when interacting with unmanaged resources or optimizing performance-critical sections where direct memory access is required.
Code Example: Pinning an array
This code snippet initializes an integer array. The fixed
statement then 'pins' the array's first element in memory. This prevents the garbage collector from moving the array while the fixed
block is executing. Inside the fixed
block, a pointer ptr
is created, pointing to the first element of the array. This pointer allows us to directly read and modify the array's contents using pointer arithmetic. After the fixed
block completes, the array is unpinned, and the garbage collector is free to move it again. Note that modifications made within the fixed block are reflected in the original array.
using System;
public unsafe class FixedExample
{
public static void Main(string[] args)
{
int[] arr = { 10, 20, 30, 40, 50 };
fixed (int* ptr = &arr[0])
{
Console.WriteLine("Original value at index 2: " + arr[2]);
// Directly modify the value at index 2 using the pointer
ptr[2] = 100;
Console.WriteLine("Modified value at index 2: " + arr[2]);
}
// The array is now unpinned and can be moved by the GC again.
Console.WriteLine("Value at index 2 after 'fixed' block: " + arr[2]);
}
}
Concepts Behind the Snippet
The fixed
keyword is essential for working with unmanaged resources or optimizing performance-critical sections in C#. It ensures that a managed variable (typically an array or string) remains at a fixed memory location during the execution of a block of code. This is necessary because the garbage collector can move objects in memory to reduce fragmentation, which would invalidate any pointers to those objects. The fixed
keyword essentially tells the garbage collector to 'hold off' on moving the object for the duration of the fixed
block.
Real-Life Use Case
A common use case for the fixed
keyword is when interacting with native libraries (e.g., through P/Invoke). Native libraries often expect pointers to memory buffers. The fixed
keyword allows you to pass managed arrays or strings to these libraries without the risk of the garbage collector moving the data during the native call. Another use case is in high-performance scenarios where you need to directly manipulate memory to avoid the overhead of managed access.
Best Practices
fixed
block as small as possible. The longer an object is pinned, the longer the garbage collector is prevented from performing its work, which can impact performance.fixed
block for later use outside the block. The pointer becomes invalid once the fixed
block exits, as the garbage collector is then free to move the object.fixed
block. Ensure proper cleanup to prevent memory corruption or resource leaks.
Interview Tip
Be prepared to explain why the fixed
keyword is necessary and how it interacts with the garbage collector. Understanding the trade-offs between performance gains and potential garbage collection overhead is crucial. Also, be prepared to discuss scenarios where using fixed
is appropriate versus alternative approaches.
When to use them
Use the fixed
keyword when:
Memory footprint
The fixed
keyword itself doesn't directly increase the memory footprint. However, excessive use of fixed
can indirectly impact memory management because it prevents the garbage collector from compacting memory. This can lead to increased memory fragmentation and potentially higher overall memory usage.
Alternatives
Marshal.Copy
to copy the data to an unmanaged buffer.Span
provides a safer and more efficient way to work with contiguous regions of memory without requiring unsafe code or the fixed
keyword in many scenarios.
Pros
Cons
fixed
keyword necessitates the use of unsafe code, which bypasses some of the safety features of C#.fixed
block can lead to memory corruption and application crashes.
FAQ
-
What happens if I try to access the pinned array outside the 'fixed' block using the pointer?
Accessing the pinned array using the pointer outside thefixed
block is undefined behavior. The garbage collector is free to move the array once thefixed
block exits, invalidating the pointer. Attempting to dereference the pointer could lead to memory corruption or application crashes. -
Can I use the 'fixed' keyword with strings?
Yes, you can use thefixed
keyword with strings. However, strings are immutable in C#, so you can only use afixed
string pointer for reading the string's contents, not for modifying them directly. Modifying a string through afixed
pointer is extremely dangerous and can lead to unpredictable behavior.