Does using "new" on a struct allocate it on the heap or stack?
Categories:
C# Structs: Heap vs. Stack Allocation with 'new' Keyword

Demystify C# struct allocation. Understand when 'new' allocates structs on the stack, heap, or neither, and the implications for memory management and performance.
In C#, the new
keyword is commonly associated with allocating objects on the heap. However, when it comes to struct
types, its behavior can be a source of confusion. This article clarifies whether using new
on a struct
allocates it on the heap or the stack, and explores the underlying memory management principles.
Understanding Value Types and Reference Types
Before diving into struct
allocation, it's crucial to differentiate between value types and reference types in C#.
- Value Types: Directly contain their data. Examples include
int
,bool
,float
, andstruct
s. They are typically allocated on the stack where they are declared (e.g., local variables, method parameters) or inline within a containing object (e.g., a field in a class). - Reference Types: Store a reference (memory address) to their data, which is allocated on the heap. Examples include
class
es,string
s, andarray
s. The variable itself holds the reference, while the actual object data resides on the heap.
The 'new' Keyword with Structs
When you use the new
keyword with a struct
, it primarily serves to call a constructor and initialize the struct's fields. It does not inherently dictate heap allocation for the struct
itself. The actual memory location (stack or heap) depends on where the struct
instance is declared or used.
Consider the following scenarios:
flowchart TD A[Struct Declaration] --> B{Where is it declared?} B -->|Local Variable in Method| C[Allocated on Stack] B -->|Field of a Class| D[Allocated on Heap (as part of class instance)] B -->|Field of another Struct| E[Allocated inline within parent struct (stack or heap based on parent)] B -->|Method Parameter| F[Allocated on Stack (copy passed by value)] C --> G["new" calls constructor, initializes fields] D --> G E --> G F --> G
Memory Allocation Flow for C# Structs with 'new'
Scenario 1: Local Variable Structs
When a struct
is declared as a local variable within a method, it is typically allocated on the stack, regardless of whether new
is used. The new
keyword simply ensures that the struct's constructor is called to initialize its fields.
public struct Point
{
public int X { get; set; }
public int Y { get; set; }
public Point(int x, int y)
{
X = x;
Y = y;
}
}
public class Program
{
public static void Main()
{
// Allocated on the stack
Point p1 = new Point(10, 20);
Console.WriteLine($"p1: ({p1.X}, {p1.Y})");
// Also allocated on the stack, default constructor called implicitly
Point p2;
p2.X = 5;
p2.Y = 15;
Console.WriteLine($"p2: ({p2.X}, {p2.Y})");
}
}
Local struct allocation on the stack
new
is primarily about initialization. If you don't use new
, you must manually assign values to all fields before the struct can be used, as shown with p2
.Scenario 2: Structs as Fields in a Class
If a struct
is a field within a class
, then the struct
instance will be allocated on the heap as part of the containing class instance. The new
keyword, if used in the class's constructor or field initializer, will still call the struct
's constructor, but the memory for the struct
itself is part of the heap-allocated class object.
public class Circle
{
public Point Center; // Point is a struct
public int Radius { get; set; }
public Circle(int centerX, int centerY, int radius)
{
// 'new Point' calls the struct constructor
// The 'Center' struct is allocated on the heap, as part of the Circle object
Center = new Point(centerX, centerY);
Radius = radius;
}
}
public class Program
{
public static void Main()
{
// Circle object is on the heap, and its 'Center' struct field is part of that heap allocation
Circle c = new Circle(0, 0, 5);
Console.WriteLine($"Circle Center: ({c.Center.X}, {c.Center.Y})");
}
}
Struct field allocation within a class on the heap
Scenario 3: Structs as Fields in Another Struct
When a struct
contains another struct
as a field, the inner struct
is allocated inline within the outer struct
. Its ultimate location (stack or heap) then depends on where the outer struct
is allocated.
public struct Rectangle
{
public Point TopLeft; // Point is a struct
public Point BottomRight; // Point is a struct
public Rectangle(int x1, int y1, int x2, int y2)
{
// 'new Point' calls constructors
// TopLeft and BottomRight structs are allocated inline within the Rectangle struct
TopLeft = new Point(x1, y1);
BottomRight = new Point(x2, y2);
}
}
public class Program
{
public static void Main()
{
// Rectangle struct is allocated on the stack
// TopLeft and BottomRight are also on the stack, nested within Rectangle
Rectangle rect = new Rectangle(0, 10, 20, 0);
Console.WriteLine($"Rectangle TopLeft: ({rect.TopLeft.X}, {rect.TopLeft.Y})");
}
}
Nested struct allocation
struct
s are value types. Their allocation location is determined by the context in which they are declared, not by the new
keyword itself. The new
keyword for structs primarily ensures proper initialization via a constructor.