Skip to main content
An unsafe context in C# is an explicit code boundary that bypasses the Common Language Runtime’s (CLR) memory safety verifications, permitting the direct manipulation of memory using raw pointers. Within this context, the developer assumes full responsibility for memory management, bounds checking, and type safety—operations normally enforced by the runtime and the Garbage Collector (GC).

Enabling Unsafe Code

Because unsafe code introduces potential memory corruption and security risks, the C# compiler rejects it by default. To compile unsafe code, the project must explicitly opt-in by adding the <AllowUnsafeBlocks>true</AllowUnsafeBlocks> property to the .csproj file, or by passing the -unsafe flag to the compiler.

Declaration Syntax

The unsafe modifier establishes the context. It can be applied at various scopes, including entire types, members, or isolated statement blocks.

Pointer Mechanics and Restrictions

Inside an unsafe context, C# exposes C-style pointer operators:
  • * : Pointer declaration and dereferencing.
  • & : Address-of operator (returns the memory address of a variable).
  • -> : Member access through a pointer.
  • [] : Pointer element access (pointer arithmetic).
Unmanaged Types Restriction: Pointers can only point to unmanaged types. An unmanaged type is any type that is not a reference type and does not contain reference type fields at any level of nesting. This includes primitives (int, byte, float, etc.), enum types, and struct types composed exclusively of unmanaged types. You cannot create a pointer to a string or a class.

Memory Pinning with the fixed Statement

The CLR’s Garbage Collector routinely compacts the managed heap, physically relocating objects in memory. If a raw pointer holds the address of a managed object during a GC cycle, the pointer will become invalid (a dangling pointer) when the object moves. To safely point to managed data (like an array), the fixed statement is required. It “pins” the object, instructing the GC not to relocate it for the duration of the fixed block.

Stack Allocation

The unsafe context allows the use of the stackalloc keyword to allocate a block of memory directly on the thread’s execution stack rather than the managed heap. Memory allocated via stackalloc is not subject to garbage collection and is automatically discarded when the method returns.
(Note: In modern C#, stackalloc can be used in safe contexts if assigned to a Span<T>, but assigning it to a raw pointer strictly requires an unsafe context).
Tired of Poor C# Skills? Fix That With Deep Grasping!Learn More