Using Span<T> for Zero‑Allocation Memory Operations in .NET
Learn how to use Span<T> with stackalloc for zero‑allocation memory work in .NET, including setup, safe usage patterns, analyzer checks, and rollback strategies.
16 Aug 2026, 03:34 UTC

Desired outcome
Perform memory‑intensive operations such as parsing or buffering without allocating objects on the managed heap, by using Span<T> backed by stack‑allocated memory.
Prerequisites
- .NET SDK version 6.0 or later (the examples target .NET 6+, but the feature exists from .NET Core 2.1/.NET 5).
- A project that targets a framework supporting ref structs (e.g., .NET 5, .NET Core 3.1, .NET 6+).
- Basic familiarity with C# syntax and the concept of ref structs.
Procedure
Create a stack‑allocated buffer using
stackalloc. This allocates memory on the current thread’s stack, which is automatically reclaimed when the method returns.// Example: allocate 256 bytes on the stack Span<byte> buffer = stackalloc byte[256];Pass the
Span<byte>to APIs that acceptReadOnlySpan<byte>orSpan<T>. Many .NET libraries (e.g.,System.Text.Json,System.Buffers.Binary) have overloads for span types.// Parse a two‑byte integer from the buffer without heap allocation ushort value = System.Buffers.Binary.BinaryPrimitives.ReadUInt16LittleEndian(buffer);Ensure the span does not escape the method’s scope. Storing a
Span<T>in a field, returning it, or capturing it in a lambda leads to undefined behavior because the underlying stack memory may be reclaimed.// ❌ Incorrect: storing the span in a class field private Span<byte> _field; void BadMethod() { _field = stackalloc byte[10]; // _field now points to reclaimed memory } // ✅ Correct: use the span only within the method void GoodMethod() { Span<byte> local = stackalloc byte[10]; // work with local }Enable .NET analyzers to detect unsafe span usage. Add the following to your
.csprojif not already present:<PropertyGroup> <EnableNETAnalyzers>true</EnableNETAnalyzers> <AnalysisMode>All</AnalysisMode> </PropertyGroup>Run the build and inspect analyzer warnings. Rule
CA1860flags allocations inside ref structs; ruleCA2235marks unsafe span escapes.dotnet build
Expected checks
- Build succeeds with no CS0103 or CS0246 errors related to
Span<T>. - Analyzer output shows zero warnings for
CA1860andCA2235in the files using spans. - Runtime execution completes without access‑violation exceptions (which would indicate an escaped span).
Recovery options
If you discover that a span is being stored incorrectly, revert to a heap‑allocated alternative such as byte[] or Memory<T> for the affected code path. This eliminates the risk of undefined behavior at the cost of an allocation.
// Safe fallback using a rented array from ArrayPool
byte[] rented = ArrayPool<byte>.Shared.Rent(256);
try
{
Span<byte> buffer = rented;
// use buffer as before
}
finally
{
ArrayPool<byte>.Shared.Return(rented);
}
Remember to return rented arrays to the pool to avoid leaks.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.