将字符串复制到字符串结构中

时间:2018-08-28 11:34:36

标签: go memcpy unsafe-pointers

我正在尝试使用unsafe.Pointer在Go语言中从C模拟memcpy。 我必须通过以下方式将字符串映射到字符串结构中:

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 :(得分:3)

您没有为结构值保留足够的内存。结构值是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