I am quite confused about the array in a slice. Code is posted below.
I understand test() takes a copy of arr from main(), and the 'append' in test() doesn't allocate a new array because cap > len.
However, it seems that the underlying array in the test slice arr[] and main slice arr[] are different, since their addresses are different.
On the other hand, the 'append' operation in test() does modify the underlying array in the main(), because a new '1' appears when the underlying array of the main slice gets printed. Also, test() is able to set arr[0] = 10, which is visible in main().
How does this happen?
The address of array in slice is taken from this post.
func test(arr []int) {
arr[0] = 10
fmt.Printf("test slice - %p \n", &arr) //
hdr := (*reflect.SliceHeader)(unsafe.Pointer(&arr))
data := *(*[10]int)(unsafe.Pointer(hdr.Data))
fmt.Printf("test - %p \n", &data)
arr = append(arr, 1)
fmt.Printf("test slice = %p \n", &arr) //
hdr = (*reflect.SliceHeader)(unsafe.Pointer(&arr))
data = *(*[10]int)(unsafe.Pointer(hdr.Data))
fmt.Printf("test = %p \n", &data)
}
func main() {
var arr []int = make([]int, 4, 10)
hdr := (*reflect.SliceHeader)(unsafe.Pointer(&arr))
data := *(*[10]int)(unsafe.Pointer(hdr.Data))
fmt.Printf("main - %p \n", &data)
test(arr)
hdr = (*reflect.SliceHeader)(unsafe.Pointer(&arr))
data = *(*[10]int)(unsafe.Pointer(hdr.Data))
fmt.Printf("main = %p \n", &data)
fmt.Println("main data ", data)
}
Output:
main - 0xc00009e050
test slice - 0xc0000a6000
test - 0xc00009e0a0
test slice = 0xc0000a6000
test = 0xc00009e0a0
main = 0xc00009e050
main data [10 0 0 0 1 0 0 0 0 0]