Golang中指针的内存变化机制是什么?

Golang中指针的内存变化机制是什么? 我对地址的工作原理感到困惑。当我运行下面的应用程序时,得到这样的结果:

&abc                abc                   *abc
0xc42000c028 0xc420014080 5
0xc42000c028 0xc4200140a0 20

所以,&abc 是数据的地址,*abc 是由 abc 地址指向的数据。

最后,单独的 abc 是什么?这是 abc 变量在内存中存储的地址吗?为什么当我创建 new(int) 时它改变了?为什么 &abc 没有改变?

package main
import "fmt"
func main() {
	abc := new(int)
	*abc = 5
	fmt.Println(&abc, abc, *abc)

    // create new abc
	abc = new(int)
	*abc = 20
	fmt.Println(&abc, abc, *abc) 
}

更多关于Golang中指针的内存变化机制是什么?的实战教程也可以访问 https://www.itying.com/category-94-b0.html

3 回复

abc := new(int) 创建一个 *int 并赋值给 abc

abc 本身有一个地址,你可以通过使用 & 来获取它。因此 &abc 是存储值(类型为 *int)的内存位置。

接下来,正如我们之前所说,abc 是一个 *int,读作“指向整数的指针”。这同样是一个内存地址,它告诉我们可以在哪里找到一个整数。

*abc 然后将指针解析(-> 解引用)为其实际值。

当你遇到第二个 new(int) 时,它使用简单的赋值运算符(=),你重新赋值给旧的 abc,这就是为什么 &abc 没有改变。正确的表述应该是“创建一个新的 *int”,因为 abc 保持不变。

更多关于Golang中指针的内存变化机制是什么?的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


abc := new(int) 为整型变量分配内存,并返回指向该内存的指针地址。

对变量应用 & 运算符会返回指向该变量的指针,即其内存地址。对变量应用 * 运算符则会解引用指针并返回值。

因此 abc 是指向整型的指针,*abc 是整型值本身,而 &abc 是指向整型指针的地址——即指向整型指针的指针。

如果将 abc 替换为指向不同内存区域的其他指针,Go 编译器会重用被替换的变量,因此即使指向整型的指针发生了变化,指向整型指针的指针仍将保持不变。

示意图如下: bitmap

在Go语言中,指针的内存变化机制可以通过分析你的代码来理解。让我们分解每个变量的含义:

  • &abc:获取变量abc本身的地址(即指针变量的地址)
  • abc:指针变量abc的值(即它指向的内存地址)
  • *abc:解引用指针,获取指针指向地址中存储的值

在你的代码中:

package main
import "fmt"

func main() {
	abc := new(int)  // 在堆上分配int内存,abc指向该内存地址
	*abc = 5         // 在abc指向的地址中存储值5
	fmt.Println(&abc, abc, *abc)  // 输出:abc的地址 | abc的值(指向的地址) | 存储的值

	// 创建新的int分配
	abc = new(int)   // 在堆上分配新的int内存,abc现在指向新的地址
	*abc = 20        // 在新的地址中存储值20
	fmt.Println(&abc, abc, *abc)  // 输出:abc的地址 | abc的新值(新地址) | 新存储的值
}

解释你的输出结果:

  • &abc 没有改变:这是指针变量abc本身在栈上的存储地址,在整个函数执行期间保持不变
  • abc 改变了:当调用new(int)时,每次都会在堆上分配新的内存,所以指针指向的地址发生了变化
  • *abc 改变了:因为指针指向了不同的内存位置,存储的值也随之改变

内存布局示例:

第一次分配:
栈: &abc = 0xc42000c028 → 指向堆地址 0xc420014080
堆: 地址 0xc420014080 存储值 5

第二次分配:
栈: &abc = 0xc42000c028 → 指向新的堆地址 0xc4200140a0  
堆: 地址 0xc4200140a0 存储值 20

abc变量本身是一个指针,它存储的是动态分配内存的地址。每次调用new(int)都会返回不同的内存地址,因此abc的值会改变,但abc变量自己的地址(&abc)在函数栈帧中是固定的。

回到顶部