首页  >  文章  >  后端开发  >  当 Go 将切片移动到内存中的另一个位置时,指向元素的指针会发生什么?

当 Go 将切片移动到内存中的另一个位置时,指向元素的指针会发生什么?

WBOY
WBOY转载
2024-02-08 22:00:27411浏览

当 Go 将切片移动到内存中的另一个位置时,指向元素的指针会发生什么?

在Go语言中,当切片被移动到内存中的另一个位置时,指向元素的指针会发生变化。由于切片是一个动态数组,其底层数据结构包含指向数组元素的指针以及切片的长度和容量信息。当切片被重新分配或扩容时,原来指向的元素指针将不再有效。因此,如果在切片被移动后仍然使用之前的指针,可能导致访问错误的内存位置或者引发其他异常。为了避免这种情况,我们应该在切片被移动后重新获取指向元素的指针,以确保指针的有效性和正确性。通过重新获取指针,我们可以在切片移动后继续正确地操作和访问切片中的元素。

问题内容

我有以下代码

package main

import "fmt"

func main() {
    a := []int{1}
    b := &a[0]
    fmt.Println(a, &a[0], b, *b) // prints [1] 0xc00001c030 0xc00001c030 1

    a = append(a, 1, 2, 3)
    fmt.Println(a, &a[0], b, *b) // prints [1 1 2 3] 0xc000100020 0xc00001c030 1
}

首先它创建一个 1 int 的切片。它的 len 是 1,cap 也是 1。然后我获取一个指向它的第一个元素的指针,并在 print 中获取底层指针值。正如预期的那样,它工作得很好。

然后我向切片中添加了 3 个元素,从而扩展了切片的容量,从而将其复制到内存中的另一个位置。之后,我打印切片第一个元素的地址(通过获取指针),该地址现在与 b 中存储的地址不同。

但是,当我打印 b 的基础值时,它也可以正常工作。我不明白为什么它有效。据我所知,第一个元素 b 的基础值时,它也可以正常工作。我不明白为什么它有效。据我所知,第一个元素

指向的切片已复制到内存中的另一个位置,因此它之前的内存肯定已被释放。不过,它似乎仍然存在。

如果我们查看映射,golang 甚至不允许我们通过键在元素上创建指针,因为完全相同的问题 - 底层数据可以移动到内存中的另一个位置。然而,它对于切片来说效果非常好。为什么会这样呢?它到底是如何运作的?内存没有被释放是因为仍然有一个变量指向该内存吗?它与地图有何不同?

解决方法

当 Go 将切片移动到内存中的另一个位置时,指向元素的指针会发生什么?

什么都没有。

b[W]当我打印

的基础值时,它也可以正常工作。我不明白为什么它会起作用。

为什么不起作用?

b最初指向的内存位置仍然存在,没有改变。只要任何东西(例如

)仍然引用它,它就仍然可用。一旦对该内存的所有引用都被删除(即超出范围),垃圾收集器可能会允许它被其他东西使用。🎜

以上是当 Go 将切片移动到内存中的另一个位置时,指向元素的指针会发生什么?的详细内容。更多信息请关注PHP中文网其他相关文章!

声明:
本文转载于:stackoverflow.com。如有侵权,请联系admin@php.cn删除