Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.syntblaze.com/llms.txt

Use this file to discover all available pages before exploring further.

A fixed-size buffer is a contiguous block of memory allocated directly inline within a struct data structure, defined using the fixed modifier. Unlike standard C# arrays, which are reference types allocated on the managed heap, fixed-size buffers embed their elements directly into the memory layout of the containing struct. This bypasses garbage collection tracking and requires an unsafe context.

Syntax and Declaration

To declare a fixed-size buffer, the containing type must be a struct, and the declaration must occur within an unsafe context.
public unsafe struct FixedBufferStruct
{
    // Allocates 64 bytes (16 * 4 bytes) directly inside the struct
    public fixed int Data[16];
}

Technical Constraints

  1. Permitted Element Types: The element type of a fixed-size buffer is strictly limited to the following primitive types: bool, byte, char, short, int, long, sbyte, ushort, uint, ulong, float, or double. Other unmanaged types, including custom structs and pointers, are strictly prohibited. Attempting to use a pointer or custom struct will result in compiler error CS1663.
  2. Struct Confinement: Fixed-size buffers can only be declared as instance fields within a struct. They cannot be declared in class types or as local variables.
  3. Compile-Time Sizing: The size of the buffer must be a compile-time constant expression greater than zero.

Memory Layout

The primary technical distinction of a fixed-size buffer is its memory footprint.
// Standard Array Layout
public struct StandardStruct
{
    // Size: 8 bytes (on 64-bit architecture). 
    // Holds a reference pointing to an array on the managed heap.
    public int[] Data; 
}

// Fixed-Size Buffer Layout
public unsafe struct FixedStruct
{
    // Size: 40 bytes (10 elements * 4 bytes per int).
    // The data is physically located inside the struct's memory footprint.
    public fixed int Data[10]; 
}
Because the memory is inline, if the struct is allocated on the stack, the buffer is on the stack. If the struct is embedded in a heap-allocated class, the buffer is allocated inline within that object’s heap memory.

Access and Pointer Arithmetic

Accessing elements of a fixed-size buffer utilizes standard array indexing syntax, but the C# compiler translates this directly into pointer arithmetic. Bounds checking is not enforced by the runtime, making buffer overruns a potential risk. When a struct containing a fixed-size buffer is allocated on the stack as a local variable, its memory is already unmovable. Attempting to use the fixed statement to pin it results in compiler error CS0213 (“You cannot use the fixed statement to take the address of an already fixed expression”). Instead, you assign the buffer directly to a pointer. (Note: If the struct resides on the managed heap as a field of a class, you must pin the class instance using the fixed statement before acquiring a pointer to the buffer.)
public unsafe void ManipulateBuffer()
{
    FixedBufferStruct instance = new FixedBufferStruct();

    // Direct index access (translated to pointer arithmetic)
    instance.Data[0] = 42;

    // Because 'instance' is a local stack variable, it is already fixed.
    // Direct pointer assignment is permitted without a 'fixed' block.
    int* ptr = instance.Data;
    
    // Pointer arithmetic
    *(ptr + 1) = 84; 
}

C# 12 InlineArray (Safe Alternative)

In C# 12, the runtime introduced a safe, managed equivalent to the unsafe fixed-size buffer using the [InlineArray] attribute. This provides the same inline memory layout characteristics without requiring the unsafe keyword or pointers.
[System.Runtime.CompilerServices.InlineArray(16)]
public struct SafeFixedBuffer
{
    // A single element defines the type; the attribute defines the length.
    private int _element0;
}

public void UseSafeBuffer()
{
    SafeFixedBuffer buffer = new SafeFixedBuffer();
    buffer[0] = 42; // Safe, bounds-checked access
}
Master C# with Deep Grasping Methodology!Learn More