go 40 lines · 7 steps

How Go slices grow and share memory

A close look at when append reuses a slice's backing array and when it quietly allocates a new one.

Explained by highlit
1package main
2 
3import "fmt"
4 
5// growSlice demonstrates how append grows a slice's underlying array.
6// When len == cap, append allocates a new, larger backing array and
7// copies the existing elements, so the slice header's data pointer changes.
8func growSlice(n int) {
9 s := make([]int, 0)
10 prevCap := cap(s)
11 
12 for i := 0; i < n; i++ {
13 s = append(s, i)
14 if cap(s) != prevCap {
15 fmt.Printf("len=%-3d cap grew %-3d -> %-3d\n", len(s), prevCap, cap(s))
16 prevCap = cap(s)
17 }
18 }
19}
20 
21// sharedBackingArray shows that appending within capacity mutates the
22// shared backing array, while exceeding capacity detaches the slice.
23func sharedBackingArray() {
24 base := make([]int, 3, 5)
25 for i := range base {
26 base[i] = i + 1
27 }
28 
29 view := append(base, 99) // fits in cap: writes into base's array
30 fmt.Println("base:", base, "len/cap:", len(base), cap(base))
31 fmt.Println("view:", view, "len/cap:", len(view), cap(view))
32 
33 // Grow beyond cap: append reallocates, view no longer shares with base.
34 for i := 0; i < 4; i++ {
35 view = append(view, 100+i)
36 }
37 view[0] = -1 // does not affect base anymore
38 fmt.Println("after realloc base:", base)
39 fmt.Println("after realloc view:", view, "cap:", cap(view))
40}
01 / 01
STEP 01

Walkthrough

Space play step click any line
Three takeaways
  1. 1append only allocates a new backing array when length would exceed capacity; otherwise it writes in place.
  2. 2Two slices can share the same backing array, so writes through one can be visible through the other.
  3. 3Once append reallocates, the resulting slice is detached and mutations no longer propagate to the original.

Related explainers

Share this explainer

Here's the card — post it anywhere.

How Go slices grow and share memory — share card
Made with highlit — turn any snippet into a walkthrough like this in about a minute.
Explain your code