Why new Vector3() Doesn’t Allocate on the Heap in Unity
In Unity, Vector3
is defined as a struct
, meaning it’s a value type, not a reference type. That distinction is critical when understanding how memory works in C#.
In this post, we'll look at how new Vector3()
behaves, and why it doesn't involve heap allocation.
What Does new Vector3() Really Do?
Vector3 pos = new Vector3();
This line creates a Vector3
on the stack, initializes it to (0, 0, 0), and then assigns it to the variable pos
.
First, new Vector3()
allocates space on the stack and initializes its values to zero. Then, the assignment to pos
creates another variable on the stack, and the initialized values are copied over.
Because Vector3
is a value type, this assignment results in a deep copy—new memory is used for the copy.
Do You Really Need new?
Since Vector3
is a struct (value type), you might wonder if using new
is really necessary.
The answer is yes—because in C#, value types must be fully initialized before use. Using new
helps initialize all fields with default values (like 0 for floats).
Consider this example:
Vector3 pos;
Debug.Log(pos); // Error: Use of unassigned local variable
Now compare with:
// Fully initialized to (0, 0, 0)
Vector3 pos = new Vector3();
You can also initialize each field manually:
Vector3 pos;
pos.x = 1;
pos.y = 2;
pos.z = 3; // All fields assigned manually
But using new
is shorter, safer, and expresses intent clearly.
A More Efficient Alternative: Vector3.zero
Instead of using new Vector3();
to create the default value (0, 0, 0) on the stack, you can use Vector3.zero
.
// No need for temporary stack storage
Vector3 pos = Vector3.zero;
Vector3.zero
is a static member of the Vector3
struct that provides the default value (0, 0, 0) in advance.
By using Vector3.zero
, you can avoid unnecessary memory allocation and improve performance.
The internal implementation of Vector3.zero
is as follows:
public static readonly Vector3 zeroVector = new Vector3(0, 0, 0);
By using Vector3.zero
, you save memory and enhance performance. This is especially efficient when you need the default value but don't want to allocate a new instance.
Value Types vs Reference Types
Value Types (struct):
- Store actual data directly.
- Copy the value when assigned or passed.
- Each copy is independent.
Reference Types (class):
- Store references (pointers) to memory locations.
- Copy the reference, not the object.
- All references point to the same instance.
Comparison Example
Value Type (struct) Example:
Vector3 a = new Vector3(1, 2, 3);
Vector3 b = a;
b.x = 10;
Debug.Log(a.x); // 1
Debug.Log(b.x); // 10
Modifying b
doesn’t affect a
—they are separate copies.
Reference Type (class) Example:
class Player {
public int health;
}
Player p1 = new Player();
Player p2 = p1;
p2.health = 50;
Debug.Log(p1.health); // 50
Since both variables point to the same object, changing p2
also changes p1
.
Summary
Vector3
is a struct, meaning it’s a value type.new Vector3()
initializes the fields, but does not allocate on the heap.- Assignments between structs result in deep copies.
- Unlike reference types, structs are stored directly on the stack (when used locally).
Personal Note
If you're coming from C++, the use of new
might feel dangerous—after all, in C++, it usually means heap allocation. I felt that discomfort too.
But in C#, and especially in Unity, using new Vector3()
is totally safe. It's just an initializer for a struct. The memory is allocated on the stack and automatically cleaned up when the block ends.
void SomeFunction()
{
Vector3 position = new Vector3(1f, 2f, 3f);
Debug.Log(position); // Prints fine
}
// After this, 'position' is gone — no garbage collection needed
So next time you write new Vector3()
, you can stop worrying—there's no hidden cost here.