Lye Fish
Lye Fish

Reputation: 2568

What happens to the 'capacity' memory when using unsafe to convert a []byte to a string?

I have seen people use unsafe.Pointer to efficiently convert a []byte to a string. https://play.golang.org/p/uz84H54VM8

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

I understand what it is doing as well as the dangers involved in general but have a question about the memory.

Since the structure of a slice has a data pointer, a length, and a capacity, but the string doesn't have the capacity, what happens to that memory if b was created on the heap? Does the garbage collector know that it needs to track the capacity separately? Or could this cause a memory leak?

EDIT:

I understand how to reslice strings and slices. The above code is for when you need to convert from []byte to string but want to avoid a full copy.

The question is about the capacity that we're dropping from the structure and if it causes GC problems.

Upvotes: 3

Views: 88

Answers (1)

Thundercat
Thundercat

Reputation: 120941

The statement var s = *(*string)(unsafe.Pointer(&b)) copies the data and length from a slice header value to a string header value.

The statement does not change the runtime's interpretation of the slice header. The capacity is not dropped from the slice header.

Copying the data and length only does not cause GC problems.

  • The string header and slice header values are both valid after the copy operation.
  • The garbage collector does not assume that the size of a string backing array is equal to the length in the string header. For example, the GC handles the safe code s := "foobarxxx"[:6] where the string header s has length 6 and the backing array has size 9.

Upvotes: 3

Related Questions