Creating Slices or Arrays from unsafe.Pointer in Golang: An Efficient Alternative
Pointers to arrays can be represented as uintptr values in Golang. However, accessing the original array can be challenging when the pointer is stored as a uintptr.
Inefficient Method: Memory Copying
One naive approach is to copy the data from the pointer into a new slice:
data := make([]byte, size) stepSize := unsafe.Sizeof(data[0]) for i := 0; i < size; i++ { data[i] = *(*byte)(unsafe.Pointer(p)) p += stepSize }
This method is inefficient as it involves copying data, which can be time-consuming for large arrays.
Efficient Method: Reflect.SliceHeader
A more efficient approach is to use reflect.SliceHeader to create a slice or array without copying memory:
var data []byte sh := (*reflect.SliceHeader)(unsafe.Pointer(&data)) sh.Data = p sh.Len = size sh.Cap = size fmt.Println(data)
This method converts the uintptr to a reflect.SliceHeader and modifies its fields to point to the existing array. The resulting slice or array will share the same underlying memory as the original array.
Alternative Method: Composite Literal
Another alternative is to use a composite literal to create a reflect.SliceHeader:
sh := &reflect.SliceHeader{ Data: p, Len: size, Cap: size, } data := *(*[]byte)(unsafe.Pointer(sh)) fmt.Println(data)
This approach produces the same result as the previous method.
Precautions
When using uintptr pointers, it's important to ensure that the original array remains valid throughout the lifetime of the pointer. Additionally, package unsafe should be used cautiously due to its potential impact on type safety.
The above is the detailed content of How to Efficiently Create Go Slices or Arrays from unsafe.Pointer?. For more information, please follow other related articles on the PHP Chinese website!