英文:
Will a slice allocate a new memory space when len is changed?
问题
package main
import "fmt"
func main() {
arr := make([]int, 3, 4)
fmt.Println(fmt.Sprintf("切片操作前:长度:%d,容量:%d,地址:%p", len(arr), cap(arr), &arr))
arr = arr[1:2]
fmt.Println(fmt.Sprintf("切片操作后:长度:%d,容量:%d,地址:%p", len(arr), cap(arr), &arr))
}
切片操作前:长度:3,容量:4,地址:0xc0000a6020
切片操作后:长度:1,容量:3,地址:0xc0000a6020
切片操作前后的地址是相同的。
我的问题是,当切片的长度从3变为1时,切片会分配新的内存吗?
因为切片包含三个元素:Data uintptr、Len int、Cap int。
如果其中一个发生变化,我猜测会在内存中生成一个新的切片,这是正确的吗?
英文:
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))
}
before len:3,cap:4, address:0xc0000a6020
after len:1,cap:3, address:0xc0000a6020
the address before and after the slicing is the same.
My question is, will the slice allocate a new memory when its len is changed from 3 to 1.
Because slice have three-element, Data uintptr, Len int, Cap int
If one of them changes, My guess is that a new slice will be generated on the memory, is that true?
答案1
得分: 4
一个切片在增长到超过其容量时会重新分配其数据,但是头部不会移动。你可以通过&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]))
}
(https://play.golang.org/p/Rtvt16DH_tj)
英文:
A slice will reallocate its Data if it grows larger than its capacity, but the header will not move. You would see this with &arr[0]. If you copy a slice, you get a new, different header, but they will share data, until the original or copy's data is reallocated.
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]))
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论