2017-02-13 39 views
3

我看到有人用unsafe.Pointer高效地將[]byte轉換爲stringhttps://play.golang.org/p/uz84H54VM8使用不安全將[]字節轉換爲字符串時,'容量'內存會發生什麼變化?

var b = []byte{'f', 'o', 'o', 'b', 'a', 'r'} 
var s = *(*string)(unsafe.Pointer(&b)) 

我明白它在做什麼,以及參與一般的危險,但有一個關於內存的問題。

由於切片的結構具有數據指針,長度和容量,但該字符串沒有容量,因此如果在堆上創建了b,那麼該內存會發生什麼情況?垃圾收集器是否知道需要分別跟蹤容量?或者這可能導致內存泄漏?

編輯:

我明白如何reslice字符串和切片。以上代碼適用於需要從[]byte轉換爲string但希望避免完整複製的情況。

問題是關於capacity,我們從結構中刪除,如果它導致GC問題。

回答

3

聲明var s = *(*string)(unsafe.Pointer(&b))將數據和長度從a slice header值複製到string header值。

該語句不會更改運行時對切片標頭的解釋。容量不會從切片頭中丟失。

僅複製數據和長度不會導致GC問題。

  • 字符串標題和切片標題值在複製操作後都有效。
  • 垃圾回收器不會假定字符串backing數組的大小等於字符串頭中的長度。例如,GC處理安全的代碼s := "foobarxxx"[:6]其中字符串頭s具有長度6和背襯陣列具有大小9.
+0

謝謝但這始於一個字符串。我上面顯示的代碼是當你給了一個'[]字節',但需要將它轉換爲一個字符串,並且希望避免複製。 –

+0

@LyeFish查看更新的答案 –

+0

好的,這很有道理。 's'是頭部的副本,因此數據指針和長度被複制到新的內存中,原始頭部是一個完全獨立的實體,可以單獨跟蹤。謝謝! –

相關問題