Invalid memory address or nil pointer dereference when appending to slice of structs
go, slice, struct
Solution
For example,
package main
import (
"fmt"
)
type Person struct {
name string
}
func main() {
p := make([]*Person, 1) //Changed to 1 instead of 0
fmt.Println(len(p), p)
p = append(p, &Person{"Brian"})
fmt.Println(len(p), p)
fmt.Println(p[1].name)
fmt.Println(p[0])
fmt.Println(p[0].name)
}
Output:
1 [<nil>]
2 [<nil> 0x10500190]
Brian
<nil>
panic: runtime error: invalid memory address or nil pointer dereference
`p` has length 1 before the append, length 2 after. Therefore, `p[0]` has the uninitialized pointer value `nil` and `p[0].name` is invalid.
The Go Programming Language Specification
Appending to and copying slices
The variadic function append appends zero or more values x to s of type S, which must be a slice type, and returns the resulting slice, also of type S.
Pointer types
The value of an uninitialized pointer is nil.
Selectors
The following rules apply to selectors:
4) If x is of pointer type and has the value nil and x.f denotes a struct field, assigning to or evaluating x.f causes a run-time panic.
Problem
``` package main import ( "fmt" ) type Person struct { name string } func main() { p := make([]*Person, 0) p = append(p, &Person{"Brian"}) fmt.Println(p[0].name) p = append(p, &Person{"Le Tu"}) fmt.Println(p[1].name) } ``` The above works fine. ``` package main import ( "fmt" ) type Person struct { name string } func main() { p := make([]*Person, 1) //Changed to 1 instead of 0 p = append(p, &Person{"Brian"}) fmt.Println(p[0].name) p = append(p, &Person{"Le Tu"}) fmt.Println(p[1].name) } ``` The above panics. My understanding of `append` was that it hid the mechanics of extending/adding. Clearly, my mental model of using `append` as a sort of "push" for slices is incorrect. Can anyone explain to me why the second sample above panics? Why can't I just `append` my struct?