数组 – 如何在golang中的数组unsafe.Pointer中创建数组或切片?
一个指向数组的指针,让我们说:
p := uintptr(unsafe.Pointer(&array)) size := 5 我无法访问变量数组,上面的代码用于使其更清晰. 另外,我知道数组的大小,但是大小不是常量,它会根据运行时间而变化. 现在,我想用已知的指针,大小以及数据类型初始化切片或数组. 我想出了以下代码: data := make([]byte,size) stepSize := unsafe.Sizeof(data[0]) for i := 0; i < size; i++ { data[i] = *(*byte)(unsafe.Pointer(p)) p += stepSize } fmt.println(data) 但是这个方法会进行内存复制,这可能是效率低下的,无论如何都没有复制? 附:我也尝试了以下两种方法, // method 1 data := *(*[]byte)(unsafe.Pointer(p)) // method 2 data := *(*[size]byte)(unsafe.Pointer(p)) 但它会在运行时失败,我现在知道它的原因. 解决方法
前言:
您应该知道:如果您将指针作为uintptr类型的值,则不会阻止原始数组进行垃圾回收(uintptr值不计入引用).所以在使用这样的值时要小心,不能保证它会指向有效的值/内存区域. 从包
一般建议:尽可能远离包装不安全.留在Go的类型安全. 声明切片类型的变量,并使用不安全的转换来获取其 然后,您可以使用指针作为SliceHeader.Data值修改其字段,并将大小修改为SliceHeader.Len和SliceHeader.Cap. 完成此操作后,slice变量将指向与初始指针相同的数组. arr := [10]byte{0,1,2,3,4,5,6,7,8,9} size := len(arr) p := uintptr(unsafe.Pointer(&arr)) var data []byte sh := (*reflect.SliceHeader)(unsafe.Pointer(&data)) sh.Data = p sh.Len = size sh.Cap = size fmt.Println(data) runtime.KeepAlive(arr) 输出(在Go Playground上试试): [0 1 2 3 4 5 6 7 8 9] 请注意,我使用了 或者,您可以使用composite literal创建一个reflect.SliceHeader,并使用不安全的转换从中获取切片,如下所示: sh := &reflect.SliceHeader{ Data: p,Len: size,Cap: size,} data := *(*[]byte)(unsafe.Pointer(sh)) fmt.Println(data) runtime.KeepAlive(arr) 输出将是相同的.在Go Playground尝试这个. 这个可能性/用例记录在
(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |