How does Go allocate memory when using new(string)

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

How does Go allocate memory when using new(string)

问题

考虑以下代码:

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 个字节。那么,Go 语言是如何允许将任意大小的字符串赋值给指针所指向的位置的呢?

英文:

Consider the following code:

    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)

In the second line, p := str both pointers point to the same location, the memory address where new(string) allocated the default value of a string, an empty string. I would have expected *str = "abc" to be a problematic assignment (in c for example, this could overwrite memory). But not only does this work and p take on the same value, it also seems to continue to work if I set *str to be some very large string.

I would expect that str is pointing to a location that has a fixed number of bytes allocated to it. For a default string value, that seems to be 16 bytes. How does golang allow the assignment of some arbitrarily sized string to the location of a pointer?

答案1

得分: 3

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

正确。

我本来以为 str = "abc" 是一个有问题的赋值语句(在C语言中,这可能会覆盖内存)。但是不仅这个语句可以正常工作,p也会获得相同的值,而且如果我将str设置为一个非常大的字符串,它似乎仍然可以正常工作。

你的期望是完全错误的。Go语言不同于C语言,Go语言中的字符串的表示方式与C语言中的不同。

我本来以为str指向的是一个有固定字节数分配的位置。

这是正确的。任何类型都有一些定义好的固定大小。这是Go语言的一个特性。

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

不对。1. 字符串变量的大小与字符串内容无关(参见上文)。2. 这是与平台相关的。3. 是的,在64位系统上,16个字节等于2个字。

Golang如何允许将任意大小的字符串赋值给指针所指向的位置?

类型为string的变量并不保存实际的字符串内容,它只是一个由大约两个字(长度,指向实际内容的指针)组成的描述符。*str = "abc"并不是将"abc"存储在字符串变量中,而是将"abc"存储在某个地方,并使指向实际内容的指针指向那里。在Go语言中,类型string与C语言中的char*不同。

英文:

>In the second line, p := str both pointers point to the same location, the memory address where new(string) allocated the default value of a string, an empty string.

Correct

> I would have expected *str = "abc" to be a problematic assignment (in c for example, this could overwrite memory). But not only does this work and p take on the same value, it also seems to continue to work if I set *str to be some very large string.

Your expectation is just plain wrong. Go is not C and strings are represented differently in Go than in C.

> I would expect that str is pointing to a location that has a fixed number of bytes allocated to it.

Thats true. Any type has some defined fixed size. This is a feature of Go.

> For a default string value, that seems to be 16 bytes.

No. 1. This the size of the string variable is not dependent on the string content (also see above). 2. This is platform dependent. 3. Yes 16 bytes = 2 words on 64bit systems.

> How does golang allow the assignment of some arbitrarily sized string to the location of a pointer?

A variable of type string doesn't hold the actual string content, it is just a 2 word descriptor, roughly (length, pointer-to-actual-content). *str = "abc" doesn't store "abc" in the string variable: It stores "abc" somewhere and make the pointer-to-actual-content point there. The type string in Go is not what a char* is in C.

huangapple
  • 本文由 发表于 2021年5月28日 01:55:50
  • 转载请务必保留本文链接:https://go.coder-hub.com/67727535.html
匿名

发表评论

匿名网友

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

确定