On Thursday, 17 December 2020 at 18:42:54 UTC, H. S. Teoh wrote:

Are you sure?

My understanding is that capacity is always set to 0 when you shrink an array, in order to force reallocation when you append a new element. The reason is this:

        int[] data = [ 1, 2, 3, 4, 5 ];
        int[] slice = data[0 .. 4];

        writeln(slice.capacity); // 0
        writeln(data.capacity);  // 7  <--- N.B.
        slice ~= 10;

        writeln(slice); // [1, 2, 3, 4, 10]
        writeln(data);  // [1, 2, 3, 4, 5]

Notice that slice.capacity is 0, but data.capacity is *not* 0, even after taking the slice. Meaning the array was *not* deallocated.

Why is slice.capacity set to 0? So that when you append 10 to it, it does not overwrite the original array (cf. last line of code above), but instead allocates a new array and appends to that. This is the default behaviour because it's the least surprising -- you don't want people to be able to modify elements of your array outside the slice you've handed to them. If they want to append, they get a copy of the data instead.

In order to suppress this behaviour, use .assumeSafeAppend.


T

How does this connect to the array with zero elements? According to your explanation if I have understood it correctly, capacity is also indicating if the pointer has been "borrowed" from another array forcing an allocation whenever the array is modified. However, if capacity is zero when the array length is zero, then you would get a allocation as well, regardless if there was a previous allocated array.

Reply via email to