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?

3
  • modified slice example Commented Apr 30, 2017 at 16:34
  • @mkopriva Lmao hello again. Could you (again) post that as an answer so that I can accept it? Commented Apr 30, 2017 at 16:37
  • I've now added the answer with a little bit nicer solution. Commented Apr 30, 2017 at 17:01

1 Answer 1

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

Sign up to request clarification or add additional context in comments.

6 Comments

It seems that your solution does not describe the same address. I made a slight modification: play.golang.org/p/SZRl-UA3Wu
And also, shouldn't the size of the casted array be 6?
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.
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.
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 (play.golang.org/p/N7P3XonBCq). As soon as you dereference it (*c) you get a copy of its contents play.golang.org/p/fSLGpf8VnS. It's up to you which one you prefer.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.