Understanding the fixed Keyword in C#
Pinning Memory Like a Pro

Morteza Jangjoo, Senior .NET Backend Developer with 15+ years of experience in C#, ASP.NET Core, SQL Server, and Microservices. Skilled in building scalable, high-performance systems.
When working with C#, most of the time we don’t need to think about memory management. The Garbage Collector (GC) automatically allocates, moves, and frees memory for us.
But sometimes, especially when we interact with unmanaged code or use unsafe blocks, we need to make sure that a piece of memory stays exactly where it is.
That’s where the mysterious fixed keyword comes in. 🚀
What Does fixed Do?
By default, the GC can move objects around in memory (a process called compacting) to optimize memory usage.
If you take a raw pointer to a managed object, there’s no guarantee that the pointer will still be valid after the next GC cycle.
fixed pins an object in memory, telling the GC:
“Don’t move this object until I’m done with it.”
This is especially useful when you need to pass a pointer to unmanaged code or work directly with raw memory.
Example 1: Pinning an Array
using System;
class Program
{
unsafe static void Main()
{
int[] numbers = { 10, 20, 30, 40, 50 };
fixed (int* ptr = numbers)
{
for (int i = 0; i < numbers.Length; i++)
{
Console.WriteLine(ptr[i]); // Direct pointer access
}
}
}
}
Without fixed, the GC could move the numbers array around, invalidating the pointer.
With fixed, we guarantee the pointer stays valid until the block ends.
Example 2: Working with Native APIs
Let’s say you need to call a Windows API or a C library that expects a pointer.
You can pin your data and pass its address safely:
using System;
using System.Runtime.InteropServices;
class Program
{
[DllImport("user32.dll", CharSet = CharSet.Unicode)]
static extern bool SetWindowText(IntPtr hWnd, string text);
unsafe static void Main()
{
string message = "Hello from C#!";
fixed (char* p = message)
{
SetWindowText((IntPtr)123456, new string(p));
}
}
}
Here, fixed ensures that the message string is not relocated by the GC while we pass it to a native API.
Example 3: Image Processing (High Performance)
In graphics programming, we often need direct access to pixel buffers:
using System;
using System.Drawing;
using System.Drawing.Imaging;
class Program
{
static void Main()
{
Bitmap bmp = new Bitmap(100, 100);
BitmapData data = bmp.LockBits(
new Rectangle(0, 0, bmp.Width, bmp.Height),
ImageLockMode.ReadWrite,
PixelFormat.Format32bppArgb);
unsafe
{
byte* ptr = (byte*)data.Scan0;
// Pin a buffer (example usage)
fixed (byte* start = new byte[data.Stride * data.Height])
{
for (int y = 0; y < data.Height; y++)
{
for (int x = 0; x < data.Width; x++)
{
int index = y * data.Stride + x * 4;
ptr[index] = 0; // Blue
ptr[index + 1] = 0; // Green
ptr[index + 2] = 255; // Red
ptr[index + 3] = 255; // Alpha
}
}
}
}
bmp.UnlockBits(data);
bmp.Save("output.png");
}
}
Here, fixed guarantees that our memory buffer is pinned while we manipulate pixel data directly.
Important Considerations
Performance impact: Pinning prevents the GC from moving objects, which can cause memory fragmentation if overused.
Use only when necessary: You don’t need
fixedin everyday C# development. It’s mostly for interop, unsafe code, and high-performance scenarios.Prefer safe APIs when available: For many cases, classes like
Span<T>,Memory<T>, andMarshalprovide safer abstractions.
Summary
fixedis a special keyword in C# used to pin memory.It ensures a managed object won’t be relocated by the GC.
It’s essential for scenarios involving:
P/Invoke with native APIs
Unsafe pointer manipulation
High-performance graphics, networking, and data processing
Think of it as telling the GC:
“Hands off this object — I need to work with it directly.”
Have you ever used fixed in your projects? Was it for interop, performance tuning, or just curiosity? Share your experience in the comments!
I’m Morteza Jangjoo and “Explaining things I wish someone had explained to me”




