首頁  >  文章  >  後端開發  >  當 Go 將切片移動到記憶體中的另一個位置時,指向元素的指標會發生什麼?

當 Go 將切片移動到記憶體中的另一個位置時,指向元素的指標會發生什麼?

WBOY
WBOY轉載
2024-02-08 22:00:27409瀏覽

当 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 將切片移到記憶體中的另一個位置時,指向元素的指標會發生什麼?

什麼都沒有。

[W]當我列印 b 的基礎值時,它也可以正常工作。我不明白為什麼它會起作用。

為什麼不起作用?

最初指向的記憶體位置仍然存在,沒有改變。只要任何東西(例如 b)仍然引用它,它就仍然可用。一旦對該記憶體的所有引用都被刪除(即超出範圍),垃圾收集器可能會允許它被其他東西使用。

以上是當 Go 將切片移動到記憶體中的另一個位置時,指向元素的指標會發生什麼?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:stackoverflow.com。如有侵權,請聯絡admin@php.cn刪除