json.Unmarshal - capacity too high

Hello,

I recognized a strange behaviour with json.Unmarshal. You can see the code here:

https://goplay.space/#PsIMHcZRtCG

Summary: I unmarshal an one-element-List into []string. After that the result has a length of 1 which is fine but a capacity of 4 where the other elements are empty.

Is there a known reason why this happens?

The answer is in the code: https://golang.org/src/encoding/json/decode.go?s=4051:4099#L560

I don’t think it’s a strange behaviour, the length is 1 and the capacity is 4, as it should be.

Basically: a capacity of 4 is just an “optimization” as it is assumed most arrays are bigger than 1, and that saves from doing an expensive reallocation.

What you do in line 12 causes the elements to be empty: those elements are not accessible before the reslicing.

If you reslice your slice, you create a new slice with a different length, thus your result with empty elements.

What you do in line 12 causes the elements to be empty: those elements are not accessible before the reslicing.
If you reslice your slice, you create a new slice with a different length, thus your result with empty elements.

True - You are right

But in the comment above it says

// To unmarshal a JSON array into a slice, Unmarshal resets the slice length
// to zero and then appends each element to the slice.

Yes, that’s correct. It says it resets the slice length, not capacity.

That sentence just means Unmarshal overwrites any entry of an already used slice.

For example, if it writes 2 entries but there were 3 entries already, the third entry becomes invisible (and gets garbage collected.)

Capacity is another, different property which just means how much memory the slice is using and can use without having to be allocated again and copied.

1 Like

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.