Скопируйте строку в структуру строк - PullRequest
0 голосов
/ 28 августа 2018

Я пытаюсь смоделировать memcpy из C в Go, используя unsafe.Pointer. Мне нужно отобразить строку в структуру строк следующим образом:

package main

import (
    "fmt"
    "unsafe"
)

type myMessage struct {
    Field1 [30]string
    Field2 [2]string
    Field3 [4]string
    Field4 [1]string
    Field5 [1]string
}

func main() {

    var inputString string = "Abcdefghi"

    inputPtr := &inputString

    unsafePtr := unsafe.Pointer(inputPtr)

    messPtr := (*myMessage)(unsafePtr)

    var messageString myMessage = *messPtr

    fmt.Println(messageString)
}

Результат выглядит следующим образом:

./test
{[Abcdefghi  Abcdefghi  Abcdefghi  Abcdefghi  Abcdefghi  Abcdefghi  Abcdefghi  Abcdefghi  Abcdefghi  Abcdefghi  Abcdefghi  Abcdefghi  Abcdefghi  Abcdefghi  Abcdefghi ] [Abcdefghi ] [Abcdefghi  Abcdefghi ] [Abcdefghi] []}

т.е. код копирует inputString в каждую позицию конечной структуры.

Почему inputString дублируется?

1 Ответ

0 голосов
/ 28 августа 2018

Вы не резервируете достаточно памяти для вашего значения структуры. Значение структуры составляет 38 строк, но вы «копируете» только одну строку. Следовательно, оставшиеся 37 строк отражают случайную память после вашей первой строки, и это, оказывается, копии первой строки.

Зарезервируйте достаточно места для структуры, и она работает как положено:

package main

import (
        "fmt"
        "unsafe"
)

type myMessage struct {
        Field1 [30]string
        Field2 [2]string
        Field3 [4]string
        Field4 [1]string
        Field5 [1]string
}

func main() {
        var mem [38]string
        mem[0] = "Abcdefghi"

        fmt.Println("Sizeof(string) =", unsafe.Sizeof(""))
        fmt.Println("Sizeof(myMessage) =", unsafe.Sizeof(myMessage{}))
        fmt.Println("Sizeof(mem) =", unsafe.Sizeof(mem))

        unsafePtr := unsafe.Pointer(&mem)
        messPtr := (*myMessage)(unsafePtr)

        var messageString myMessage = *messPtr
        fmt.Println(messageString)
}

// Output:
// Sizeof(string) = 16
// Sizeof(myMessage) = 608
// Sizeof(mem) = 608
// {[Abcdefghi                             ] [ ] [   ] [] []}

Попробуйте на детской площадке: https://play.golang.org/p/K3N-TnBbaLP

...