Go语言中修改切片长度时是否会分配新内存空间?
Great question! Let’s break this down clearly, starting with your test code and observations.
The Test Code & Output
First, here’s your test code for reference:
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)) }
And its output:
before len:3,cap:4, address:0xc0000a6020 after len:1,cap:3, address:0xc0000a6020
Answering Your Technical Questions
1. Does changing the slice's len trigger new memory allocation?
No—slicing operations like arr[1:2] do not allocate new memory for the underlying array. They only create a new "view" into the existing array by adjusting the slice's metadata. The only time Go allocates new memory for a slice is when operations exceed the current capacity (like append when len == cap), which triggers a reallocation to expand the underlying array.
In your example, the original underlying array stays intact. The new slice just points to the second element of that array, with a len of 1 and cap of 3 (calculated as original cap minus the slice's start index: 4 - 1 = 3).
2. Does modifying any slice field (Data, Len, Cap) create a new slice instance?
Your guess is on the right track, but let’s clarify the distinction between the slice variable and the slice struct itself:
A slice in Go is a small struct with three core fields:
Data: Pointer to the first element of the underlying arrayLen: Number of accessible elementsCap: Total elements the underlying array can hold
When you perform a slicing operation, you’re creating a new slice struct with updated fields. However, in your test, you’re assigning this new struct back to the original arr variable. The address you printed (&arr) is the address of the variable itself (the memory slot where the slice struct is stored)—not the address of the slice’s Data pointer or the underlying array.
So when you run arr = arr[1:2], you’re overwriting the contents of the existing arr variable with a new slice struct (with adjusted Len, Cap, and a Data pointer shifted to the second element of the original array). The variable’s memory address stays the same, but its contents (the slice struct) have been replaced.
To confirm this, try modifying your code to print the address of the slice’s underlying data instead of the variable’s address:
fmt.Println(fmt.Sprintf("before len:%d,cap:%d, data ptr:%p",len(arr), cap(arr), &arr[0])) arr = arr[1:2] fmt.Println(fmt.Sprintf("after len:%d,cap:%d, data ptr:%p",len(arr), cap(arr), &arr[0]))
You’ll see the data ptr shifts by the size of an int (e.g., 8 bytes on 64-bit systems), proving it’s pointing to a different element in the same underlying array.
内容的提问来源于stack exchange,提问作者syoui jyo

