KDOC 189: Goでスライスがどのように保存されているか調べる

この文書のステータス

  • 作成
    • 2024-06-20 貴島
  • レビュー
    • 2024-06-20 貴島

概要

Goでスライスが、どのようにメモリに保存されているか調べる。

調べる

まず、スライスの定義は↓のようになっており、配列の先頭要素へのポインタにすぎない。

type slice struct {
	array unsafe.Pointer
	len   int
	cap   int
}

したがって、それぞれの要素を先頭にしたスライスを作り指すポインタを見ると、それぞれ位置するアドレスがわかる。

func main(){
        s1 := []byte{1, 2, 3}
        s2 := s1[1:]
        s3 := s1[2:]
        s4 := s1
        s4 = append(s4, 4)
        fmt.Printf("s1: %v, addr: %p, len: %d, cap: %d\n", s1, s1, len(s1), cap(s1))
        fmt.Printf("s2: %v, addr: %p, len: %d, cap: %d\n", s2, s2, len(s2), cap(s2))
        fmt.Printf("s3: %v, addr: %p, len: %d, cap: %d\n", s3, s3, len(s3), cap(s3))
        fmt.Printf("s4: %v, addr: %p, len: %d, cap: %d\n", s4, s4, len(s4), cap(s4))
}
s1: [1 2 3], addr: 0xc0000120e0, len: 3, cap: 3
s2: [2 3], addr: 0xc0000120e1, len: 2, cap: 2
s3: [3], addr: 0xc0000120e2, len: 1, cap: 1
s4: [1 2 3 4], addr: 0xc0000120e8, len: 4, cap: 8

図にするとこうなる。再割り当てされる位置は元の位置と空いているが、その箇所には何が入っているのだろうか。どうやって調べればよいか。

addr 0 1 2 3 4 5 6 7 8 9 a b
val  1 2 3 ? ? ? ? ? 1 2 3 4

関連