Golang 字符串复制内存地址的内存分配

cgu*_*guy 2 memory-management go

我目前正在阅读《Go 编程语言》一书,其中描述了字符串或子字符串的副本具有相似的内存地址。

s := "hello"
c := s

fmt.Println(&s, &c) // prints 0xc000010230 0xc000010240
Run Code Online (Sandbox Code Playgroud)

我的问题是,既然是精确的副本,就不应该&c相同吗?&sc

               RAM
      Address    |     Value
 &s 0xc000010230 |    "hello" <----- s
 &c 0xc000010240 |    "hello" <----- c
Run Code Online (Sandbox Code Playgroud)

mko*_*iva 7

cs实际上是两个不同的字符串标头。但两者都指向同一个"hello"

sh := (*reflect.StringHeader)(unsafe.Pointer(&s))
ch := (*reflect.StringHeader)(unsafe.Pointer(&c))
fmt.Println(sh.Data, ch.Data)
Run Code Online (Sandbox Code Playgroud)

https://go.dev/play/p/Ckl0P3g4nVo


字符串头的字段Data指向byte字符串中的第一个字段,Len字符串头的字段表示字符串的长度。您可以使用该信息来确认字符串标头指向原始字符串。

sh := (*reflect.StringHeader)(unsafe.Pointer(&s))
for i := 0; i < sh.Len; i++ {
    sp := (*byte)(unsafe.Pointer(sh.Data + uintptr(i)))
    fmt.Printf("%p = %c\n", sp, *sp)
}
Run Code Online (Sandbox Code Playgroud)

https://go.dev/play/p/LFfdxxARw1f

  • 是的,“c”和“s”是变量。正如您在问题中观察和描述的那样,“&amp;c”和“&amp;s”生成指向不同地址的指针。当然适用。 (3认同)