2

This question is similar to this one, only I want to convert a pointer and a length to a fixed-size Golang array.

For a slice, the solution was to create a struct with the relevant information, and cast it directly, as follows:

// 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))

How would you create an array for that specified memory instead?

Community
  • 1
  • 1
Awn
  • 817
  • 1
  • 16
  • 33

1 Answers1

2

It's almost the same as with slices but since Go arrays are just values laid out sequentially as opposed to being represented by a pointer, cap, and len like slices are, you don't need to define the array's memory layout.

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

mkopriva
  • 35,176
  • 4
  • 57
  • 71
  • It seems that your solution does not describe the same address. I made a slight modification: https://play.golang.org/p/SZRl-UA3Wu – Awn Apr 30 '17 at 17:31
  • And also, shouldn't the size of the casted array be 6? – Awn Apr 30 '17 at 17:34
  • Size `3` is meant to serve as an example that it doesn't have to be the same as the original array's len, it's up to you what size the new array should have, you could set it to `10` but the data after the first 6 elements might be garbage. – mkopriva Apr 30 '17 at 17:38
  • The new arrays will hold a copy of the original's data, that's why the elements of those new arrays are in a different memory location as those of the original. – mkopriva Apr 30 '17 at 17:41
  • Why is it at the same location without the * on the outside? I'd rather the new array describe the exact same memory location as the byte slice does. (i.e. no copying) – Awn Apr 30 '17 at 17:42
  • 2
    In your example `c` is not an array but a `pointer to an array`, and it's a pointer to the same address as the `data` slice, just different in type (https://play.golang.org/p/N7P3XonBCq). As soon as you dereference it (`*c`) you get a copy of its contents https://play.golang.org/p/fSLGpf8VnS. It's up to you which one you prefer. – mkopriva Apr 30 '17 at 18:03