Go Memory Allocation: var, new, and make Explained

In Go, the keywords var, new, and make are used for memory allocation, but they serve different purposes. Understanding their behavior is essential for writing correct and efficient Go code.

Using var with different types

When you declare a variable with var, the type determines whether it gets a zero value or nil.

var ptr *int
fmt.Println(ptr) // nil

Here ptr is a pointer variable; its default value is nil because no address has been assigned. Attempting to dereference it (*ptr = 10) would cause a runtime panic.

var num int
fmt.Println(num) // 0
fmt.Println(&num) // 0xc0000aa058

For value types, Go immediately allocates memory and sets the variable to its zero value. The address is valid.

var slice []int // nil slice
fmt.Println(len(slice))     // 0
fmt.Printf("%p\n", &slice) // e.g., 0x140000b6000
fmt.Println(slice == nil)  // true

When you declare a slice with var s []int, the slice header exists but its underlying array pointer is nil. Such a slice prints as [] and compares equal to nil. Slices cannot be compared with each other, only with nil.

Using new

The new built-in function allocates memory for a given type, returns a pointer to it, and initializes that memory with the zero value of the type.

n := new(int) // rarely used; i := 0 or u := &User{} is more idiomatic
fmt.Println(n)  // e.g., 0xc00000a098
fmt.Println(*n) // 0

Using new witth a slice type (though uncommon) still allocates a pointer:

s := new([]int)
fmt.Printf("%p\n", s) // pointer to a nil slice header

After new([]int), the slice header itself is allocated and zeroed (so the pointer inside is nil). It does not allocate an underlying array.

Using make

make is used exclusively for initializing slices, maps, and channels. It allocates and initializes the underlying data structure and returns the (non-pointer) value itself.

sl := make([]int, 0, 5)   // slice with length 0, capacity 5
m := make(map[string]int) // empty map
ch := make(chan int, 1)   // buffered channel

Unlike new, make does not return a pointer; it returns the initialized reference type.

Comparison of new and make

  • Both are used to memory allocation.
  • make works only on slice, map, and channel. It creates the reference type and initializes its internals, returning the type itself (not a pointer).
  • new works on any type, allocates memory for the type, zeroes it, and returns a pointer to that memory. It does not initialize any internal data structures for slices, maps, or channels; you get a pointer to a nil slice/map/channel.

In practice, you use var for declarations, make for reference types that need internal initialization, and new only when you specifically need a pointer to a zero value (though composite literals like &T{} are often preferred).

Tags: Go memory allocation var new make

Posted on Tue, 18 Aug 2026 16:54:32 +0000 by daria