【问题标题】:Converting a pointer to an array in Go在 Go 中将指针转换为数组
【发布时间】:2017-09-28 05:30:00
【问题描述】:

这个问题和this one类似,只是我想把一个指针和一个长度转换成一个固定大小的Golang数组。

对于一个切片,solution是用相关信息创建一个结构体,直接进行强制转换,如下:

// Slice memory layout
var sl = struct {
    addr uintptr
    len  int
    cap  int
}{addr, length, length}

// Use unsafe to turn sl into a []byte.
b := *(*[]byte)(unsafe.Pointer(&sl))

您将如何为该指定内存创建一个数组?

【问题讨论】:

  • @mkopriva Lmao 你好。您能否(再次)将其发布为答案,以便我接受?
  • 我现在用更好的解决方案添加了答案。

标签: arrays pointers memory go


【解决方案1】:

这与切片几乎相同,但由于 Go 数组只是 values laid out sequentially,而不是像切片一样由 pointercaplen 表示,因此您不需要定义数组的内存布局。

package main

import (
    "fmt"
    "reflect"
    "unsafe"
)

var data = []byte(`foobar`)

func main() {
    rv := reflect.ValueOf(data)

    ptr := rv.Pointer()
    b := *(*[3]byte)(unsafe.Pointer(ptr))

    fmt.Printf("%T %q\n", b, b)
}

https://play.golang.org/p/r9yi9OdDIC

【讨论】:

  • 您的解决方案似乎没有描述相同的地址。我做了一点修改:play.golang.org/p/SZRl-UA3Wu
  • 另外,转换数组的大小不应该是 6 吗?
  • Size 3 旨在作为一个示例,它不必与原始数组的 len 相同,由您决定新数组应具有的大小,您可以设置它到10,但前6个元素之后的数据可能是垃圾。
  • 新数组将保存原始数据的副本,这就是为什么这些新数组的元素与原始数组的元素位于不同的内存位置。
  • 在您的示例中,c 不是数组而是pointer to an array,它是指向与data 切片相同地址的指针,只是类型不同(play.golang.org/p/N7P3XonBCq)。只要您取消引用它 (*c),您就会得到其内容的副本 play.golang.org/p/fSLGpf8VnS。这取决于你喜欢哪一个。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多