Memory allocation while append()

I am bit confused about how memory allocation works while appending to a slice. I have this sample program:

package main

import "fmt"

func main() {
	var a []int
	a = append(a, 3)
	fmt.Println(&a[0])
	a = append(a, 5)
	fmt.Println(&a[0])
}

I see the output as:

0xc0000b6018
0xc0000b6030

I am confused about why the address of a[0] is different in both the cases. I would be very thankful for an explanation of this observation.

Use the cap builtin function to get the capacity of the slice each time. The capacity is the full length of the allocated array that the slice points into. The first append call sees that a is nil and so it allocates a slice with a capacity of 1 to hold the one element. Your next append sees there’s not enough capacity for the next element, so it allocates another backing array, 2x the capacity of the first (until you start getting to huge capacities, then it switches to growing linearly) copies the first array’s element(s) into it and then appends to it. If you initialize a with make([]int, 0, 2), then the backing array will start with the right capacity and the address of a[0] won’t change after appending the first 2 elements.

2 Likes