type slice struct {
array unsafe.Pointer
len int
cap int
}
slice结构如上代码,由三个field组成,分别是指向底层数组的指针,标识有效元素长度的len和标识空间大小的cap。
golang的slice类似于c++的vector,都是有len和cap的,当len 所以,如果len append扩容: 假设有两个切片如下: 如上代码,假设母切片占用内存8M,child切片是在parent基础上构造的占用内存1M,子切片和母切片共享同一块内存,当函数返回后,母切片已经不在使用,本该进行释放,但是由于和子切片公用一块内存未释放母切片,造成了7M的内存泄漏,正确做法应该是给子切片开辟空间,然后for循环将需要的数据从母切片拷贝到子切片上,然后返回子切片。 前边说切片的结构中又3个field:指向底层数组的指针、表示有效元素的长度len、表示空间的cap 如上两种方法种,只有方法二能成功在遍历是修改slice中的值。因为在用 for range遍历slice时,v取到的是slice中元素的拷贝,修改这个值,并不会影响元素本身。母子切片共享
parent := make([]int, 3, 5) //len=3, cap=5
child := parent[1:3] //len=2, cap=4
切片导致内存泄漏
func returnSubSlice() []int {
parent := make([]int, TOTAL)
child := parent[begin:end]
return child
}
函数参数需要传切片的指针吗
*arr = append(*arr, 9)
*arr = (*arr)[1:2]
遍历slice时修改slice
sli := []int{1, 2, 3}
//方法一
for _, v := range sli {
v = v + 1
}
//方法二
for i, v := range sli {
sli[i] = v + 1
}