[英]Golang slice append and reallocation
我最近一直在學習go,並且對重新分配發生時切片的行為有疑問。 假設我有一個指向結構的指針,例如:
var a []*A
如果我要將這個slice傳遞給另一個函數,並且我的理解是,它將在內部通過值傳遞slice頭,該header在一個單獨的goroutine上運行,並且僅從slice讀取,而啟動goroutine的函數繼續追加到切片,有問題嗎? 例如:
package main
type A struct {
foo int
}
func main() {
a := make([]*A, 0, 100)
ch := make(chan int)
for i := 0; i < 100; i++ {
a = append(a, &A{i})
}
go read_slice(a, ch)
for i := 0; i < 100; i++ {
a = append(a, &A{i+100})
}
<-ch
}
func read_slice(a []*A, ch chan int) {
for i := range a {
fmt.Printf("%d ", a[i].foo)
}
ch <- 1
}
因此,根據我的理解,由於read_slice()函數在自己的goroutine上帶有slice頭的副本運行,因此它具有指向當前后備數組的底層指針,以及調用該函數時可以訪問的大小。的。
但是,當另一個goroutine附加到切片時,如果超出容量,它將觸發重新分配。 go運行時是否不會將內存分配給read_slice()中使用的舊支持數組,因為該函數中有對它的引用?
我嘗試使用“ go run -race slice.go”運行它,但是沒有報告任何內容,但是我覺得我在這里可能做錯了什么? 任何指針將不勝感激。
謝謝!
在沒有對后備陣列的引用之前,GC不會收集后備陣列。 該程序中沒有種族。
考慮沒有goroutines的情況:
a := make([]*A, 0, 100)
for i := 0; i < 100; i++ {
a = append(a, &A{i})
}
b := a
for i := 0; i < 100; i++ {
b = append(b, &A{i+100})
}
當追加到b
分配新的支持數組時,切片a
將繼續使用前100個指針來引用支持數組。 切片a
不會懸空地指向后備陣列。
現在將goroutine添加到方案中:
a := make([]*A, 0, 100)
for i := 0; i < 100; i++ {
a = append(a, &A{i})
}
b := a
go read_slice(a, ch)
for i := 0; i < 100; i++ {
b = append(b, &A{i+100})
}
goroutine可以愉快地使用slice a
。 沒有懸掛的參考。
現在考慮問題中的程序。 它的功能與此處的最后一個片段相同。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.