Go 使用新(字符串)时如何分配内存

Go 使用新(字符串)时如何分配内存,go,Go,考虑以下代码: str := new(string) p := str fmt.Printf("Current value = %v %p\n", *str, str) *str = "abc" fmt.Printf("New value = %v %p\n", *str, str) fmt.Printf("Current value = %v %p\n", *p, p

考虑以下代码:

    str := new(string)
    p := str
    fmt.Printf("Current value = %v %p\n", *str, str)
    *str = "abc"
    fmt.Printf("New value = %v %p\n", *str, str)
    fmt.Printf("Current value = %v %p\n", *p, p)
在第二行,
p:=str
两个指针都指向同一个位置,
new(string)
在其中分配了字符串的默认值,即空字符串。我本以为
*str=“abc”
是一个有问题的赋值(例如,在c语言中,这可能会覆盖内存)。但是,这项工作不仅和p具有相同的值,而且如果我将*str设置为某个非常大的字符串,它似乎还会继续工作

我希望str指向一个分配了固定字节数的位置。对于默认字符串值,它似乎是16个字节。golang如何允许将任意大小的字符串分配到指针的位置

在第二行中,p:=str这两个指针都指向同一个位置,即new(string)分配字符串默认值的内存地址,即空字符串

正确的

我本以为*str=“abc”是一个有问题的赋值(例如,在c中,这可能会覆盖内存)。但是,这项工作不仅和p具有相同的值,而且如果我将*str设置为某个非常大的字符串,它似乎还会继续工作

你的期望完全错了。Go不是C,字符串在Go中的表示方式与在C中的不同

我希望str指向一个分配了固定字节数的位置

没错。任何类型都有定义的固定大小。这是围棋的一个特点

对于默认字符串值,它似乎是16个字节

第一。这表明字符串变量的大小不依赖于字符串内容(另请参见上文)。2.这取决于平台。3.是16字节=64位系统上的2个字

golang如何允许将任意大小的字符串分配到指针的位置


string
类型的变量不包含实际的字符串内容,它只是一个两个字的描述符,大致上(长度,指向实际内容的指针)
*str=“abc”
不将“abc”存储在字符串变量中:它将“abc”存储在某个位置,并将指针指向实际内容。Go中的类型
字符串
不是C中的
字符*

对不起,我根本不理解这个问题,指针就是这样工作的。你能解释一下混淆是什么,或者你期望会发生什么吗?哦,也许问题是字符串从根本上是如何表示的?Go字符串不像C中那样是空分隔数组,它们由带指针和长度的结构表示。不,结构是不可变的,只需重写结构即可。事实上,您可以分配值,这意味着它的大小是相同的。是的,就语言而言,它是不可变的。通过指针覆盖结构就是丢弃旧值并在其位置写入新值。如果没有
unsafe
,则不能单独直接写入长度或数据指针。
string
内部只是一个结构。字符串本身保存在该结构中的字节片中。结构大小永远不会改变,但字节片可以替换为不同长度的片。分配
字符串
与分配字节片无关。