当 len 改变时,切片会分配新的内存空间吗?

syo*_*jyo -3 memory pointers go slice

package main

import "fmt"

func main() {
    arr := make([]int,3,4)
    fmt.Println(fmt.Sprintf("before len:%d,cap:%d, address:%p",len(arr), cap(arr), &arr))
    arr = arr[1:2]
    fmt.Println(fmt.Sprintf("after len:%d,cap:%d, address:%p",len(arr), cap(arr), &arr))
}

Run Code Online (Sandbox Code Playgroud)
before len:3,cap:4, address:0xc0000a6020
after len:1,cap:3, address:0xc0000a6020
Run Code Online (Sandbox Code Playgroud)

切片前后的地址是一样的。

我的问题是,当它的 len 从 3 更改为 1 时,切片是否会分配新的内存。

因为 slice 有三个元素, Data uintptr, Len int, Cap int 如果其中一个发生变化,我的猜测是内存上会生成一个新的 slice,是真的吗?

小智 5

如果切片增长超过其容量,则切片将重新分配其数据,但标头不会移动。你会用 &arr[0] 看到这一点。如果你复制一个切片,你会得到一个新的、不同的标头,但它们会共享数据,直到原始或副本的数据被重新分配。

package main

import "fmt"

func main() {
    arr := make([]int,3,4)
    arrCopy := arr
    fmt.Println(fmt.Sprintf("before   len:%d,cap:%d, address:%p, data:%p",len(arr), cap(arr), &arr, &arr[0]))
    arr = arr[1:2]
    fmt.Println(fmt.Sprintf("after    len:%d,cap:%d, address:%p, data:%p",len(arr), cap(arr), &arr, &arr[0]))
    arr = append(arr, arrCopy...)
    fmt.Println(fmt.Sprintf("appended len:%d,cap:%d, address:%p, data:%p",len(arr), cap(arr), &arr, &arr[0]))
    fmt.Println(fmt.Sprintf("arrCopy  len:%d,cap:%d, address:%p, data:%p",len(arrCopy), cap(arrCopy), &arrCopy, &arrCopy[0]))
}
Run Code Online (Sandbox Code Playgroud)

( https://play.golang.org/p/Rtvt16DH_tj )