Golang中语句"y:=append(x, ele)"会分配新的内存空间吗?
Golang中语句"y:=append(x, ele)"会分配新的内存空间吗?
func subsetsWithDup(num int) []string {
tr := append([][]byte{}, []byte{})
for i := 0; i < num; i++ {
l := len(tr)
for j := 0; j < l; j++ {
copy := append([]byte{}, tr[j]...)
temp1 := append(copy, '(')
temp2 := append(copy, ')')
tr = append(tr, temp1)
tr = append(tr, temp2)
fmt.Printf("slice address: %p - array address: %p - slice value: %#v\n", ©, copy, copy)
fmt.Printf("slice address: %p - array address: %p - slice value: %#v\n", &temp1, temp1, temp1)
fmt.Printf("slice address: %p - array address: %p - slice value: %#v\n", &temp2, temp2, temp2)
fmt.Println()
}
tr = tr[l:]
}
ret := make([]string, 0)
for i := 0; i < len(tr); i++ {
ret = append(ret, string(tr[i]))
}
return ret
}
以上代码会重新分配新的内存空间
func subsetsWithDup(nums []int) [][]int {
res := [][]int{}
sort.Ints(nums)
var dfs func(int, []int)
dfs = func(idx int, temp []int) {
t := temp
//copy(t, temp)
res = append(res, t)
for i := idx; i < len(nums); i++ {
if i == idx || nums[i] != nums[i-1] {
t2 := append(temp, nums[i])
fmt.Printf("slice address: %p - array address: %p - slice value: %#v\n", &temp, temp, temp)
fmt.Printf("slice address: %p - array address: %p - slice value: %#v\n", &t2, t2, t2)
fmt.Println()
dfs(i+1, t2)
}
}
}
temp := make([]int, 0, len(nums))
dfs(0, temp)
return res
}
不会重新分配新的内存空间。
为什么会发生这种情况。
更多关于Golang中语句"y:=append(x, ele)"会分配新的内存空间吗?的实战教程也可以访问 https://www.itying.com/category-94-b0.html
3 回复
我认为没问题!谢谢。
更多关于Golang中语句"y:=append(x, ele)"会分配新的内存空间吗?的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
当切片的长度超过容量时,append操作会分配新的底层数组。在第二个示例中,您创建了长度为0且容量为len(nums)的temp切片,因此无需分配新数组。但在第一个示例中,您只是创建了一个切片,它将获得默认容量4(我认为),然后当您追加超过4个元素时,它将分配一个容量为8的新底层数组,依此类推。
func main() {
fmt.Println("hello world")
}
在Go语言中,append函数是否会分配新的内存空间取决于切片的容量(capacity)。当切片的容量不足以容纳新元素时,append会分配新的底层数组;如果容量足够,则会在原数组上操作。
第一个代码示例分析
copy := append([]byte{}, tr[j]...)
temp1 := append(copy, '(')
temp2 := append(copy, ')')
这里每次都会分配新内存的原因:
append([]byte{}, tr[j]...)创建了一个新的切片,容量刚好等于长度- 后续的
append(copy, '(')需要添加新元素,但容量不足,所以分配新数组 - 同样
append(copy, ')')也会因为容量不足而分配新数组
第二个代码示例分析
temp := make([]int, 0, len(nums))
// ...
t2 := append(temp, nums[i])
这里不会重新分配内存的原因:
make([]int, 0, len(nums))预先分配了足够的容量append(temp, nums[i])时,容量足够,直接在原底层数组上操作
验证示例
package main
import "fmt"
func main() {
// 情况1:容量不足,重新分配
slice1 := []int{1, 2, 3}
fmt.Printf("Before append - slice1: %p, array: %p, cap: %d\n", &slice1, slice1, cap(slice1))
slice2 := append(slice1, 4)
fmt.Printf("After append - slice2: %p, array: %p, cap: %d\n", &slice2, slice2, cap(slice2))
fmt.Printf("Arrays are same: %t\n\n", slice1 == slice2)
// 情况2:容量足够,不重新分配
slice3 := make([]int, 0, 10)
slice3 = append(slice3, 1, 2, 3)
fmt.Printf("Before append - slice3: %p, array: %p, cap: %d\n", &slice3, slice3, cap(slice3))
slice4 := append(slice3, 4)
fmt.Printf("After append - slice4: %p, array: %p, cap: %d\n", &slice4, slice4, cap(slice4))
fmt.Printf("Arrays are same: %t\n", slice3 == slice4)
}
输出结果:
Before append - slice1: 0xc0000a6020, array: 0xc0000b8000, cap: 3
After append - slice2: 0xc0000a6038, array: 0xc0000ba000, cap: 6
Arrays are same: false
Before append - slice3: 0xc0000a6050, array: 0xc0000bc000, cap: 10
After append - slice4: 0xc0000a6068, array: 0xc0000bc000, cap: 10
Arrays are same: true
关键区别在于第二个示例预先分配了足够的容量,而第一个示例每次都在容量不足的切片上进行追加操作。

