Go Pointers with Maps & Slices — Find the Bug¶
Instructions¶
Identify, explain, fix. Difficulty: 🟢 🟡 🔴.
Bug 1 🟢 — &m["key"]¶
Solution
**Bug**: Map values not addressable. Compile error. **Fix**: extract or use `map[K]*V`:Bug 2 🟢 — Append Result Discarded¶
Solution
**Bug**: `append` returns a new slice; discarding the result loses the change. Output: `[1 2 3]`. **Fix**: `s = append(s, 99)`.Bug 3 🟢 — Map Value Field Mutation¶
Solution
**Bug**: Map value field can't be modified directly (not addressable). Compile error. **Fix**: store as `map[string]*Counter` OR extract-modify-restore.Bug 4 🟡 — Stale Pointer After Append¶
Solution
**Bug**: append reallocates (cap was 3, exceeded). `p` points to the old (detached) array. `*p = 999` doesn't affect `s`. Output: `[1 0 0 99]`. **Fix**: use index `s[0] = 999` instead of cached pointer; or `p = &s[0]` after append.Bug 5 🟡 — Subslice Append Surprise¶
a := []int{1, 2, 3, 4, 5}
b := a[:3] // cap=5
b = append(b, 99)
fmt.Println(a) // expected [1 2 3 4 5]
Solution
**Bug**: `b`'s cap is 5 (inherited from `a`). `append` writes within shared backing — overwrites `a[3]`. Output: `[1 2 3 99 5]`. **Fix** (defensive copy):Bug 6 🟡 — Concurrent Map Panic¶
Solution
**Bug**: Concurrent map writes panic with "concurrent map writes". **Fix**: `sync.RWMutex`: Or `sync.Map`.Bug 7 🟡 — Loop Variable Pointer in Pre-1.22¶
Solution
**Pre-1.22**: All `&x` are the same pointer. After loop, all point to value 3. **Fix**: shadow `x := x`, OR use index `&items[i]`, OR upgrade to Go 1.22+.Bug 8 🔴 — Subslice Pinning Memory¶
big := make([]byte, 1<<20)
small := big[:10]
big = nil
runtime.GC()
// 1 MB still alive (small references the backing)
Solution
**Bug**: `small` references the backing array. The whole 1 MB stays alive. **Fix** — copy out:Bug 9 🔴 — Map Iteration Order Assumption¶
m := map[string]int{"a": 1, "b": 2, "c": 3}
for k, v := range m {
fmt.Println(k, v)
}
// Code assumes alphabetical order
Solution
**Bug**: Map iteration order is RANDOMIZED by Go (intentionally, to discourage reliance on order). Output varies. **Fix** — sort keys explicitly:Bug 10 🔴 — Storing Pointers to Loop's Slice Index¶
items := []int{1, 2, 3}
var ptrs []*int
for i := range items {
ptrs = append(ptrs, &items[i])
}
items = append(items, 99) // may realloc
fmt.Println(*ptrs[0])