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

huangapple go评论83阅读模式
英文:

Golang memory allocation for string copy memory addresses

问题

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

s := "hello"
c := s

fmt.Println(&s, &c) // 输出 0xc000010230 0xc000010240

我的问题是,既然c是一个完全的副本,那么&c不应该与&s相同吗?

               RAM
      地址       |     值
 &s 0xc000010230 |    "hello" <----- s
 &c 0xc000010240 |    "hello" <----- c
英文:

I am currently reading the Go Programming Language book which describes that a copy of a string or a substring has similar memory addresses.

s := &quot;hello&quot;
c := s

fmt.Println(&amp;s, &amp;c) // prints 0xc000010230 0xc000010240

My question is, shouldn't &amp;c be the same as &amp;s since it c is an exact copy ?

               RAM
      Address    |     Value
 &amp;s 0xc000010230 |    &quot;hello&quot; &lt;----- s
 &amp;c 0xc000010240 |    &quot;hello&quot; &lt;----- c


</details>


# 答案1
**得分**: 5

`c`和`s`实际上是两个不同的字符串头部。但它们都指向同一个`"hello"`。

```go
sh := (*reflect.StringHeader)(unsafe.Pointer(&s))
ch := (*reflect.StringHeader)(unsafe.Pointer(&c))
fmt.Println(sh.Data, ch.Data)

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


字符串头部的Data字段指向字符串中的第一个字节,字符串头部的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)
}

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

英文:

c and s are actually two distinct string headers. But both of them point to the same &quot;hello&quot;.

sh := (*reflect.StringHeader)(unsafe.Pointer(&amp;s))
ch := (*reflect.StringHeader)(unsafe.Pointer(&amp;c))
fmt.Println(sh.Data, ch.Data)

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


The Data field of the string header points to the first byte in the string and the Len field of the string header indicates the length of the string. You can use that information to confirm that the string header is pointing to the original string.

sh := (*reflect.StringHeader)(unsafe.Pointer(&amp;s))
for i := 0; i &lt; sh.Len; i++ {
	sp := (*byte)(unsafe.Pointer(sh.Data + uintptr(i)))
	fmt.Printf(&quot;%p = %c\n&quot;, sp, *sp)
}

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

huangapple
  • 本文由 发表于 2022年1月27日 21:39:08
  • 转载请务必保留本文链接:https://go.coder-hub.com/70879513.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定