Thread overview
Why does array loses it internal capacity on length change?
Mar 12, 2016
Uldis
Mar 12, 2016
JR
Mar 12, 2016
Jack Applegame
Mar 12, 2016
Adam D. Ruppe
March 12, 2016
While writing a structs function that I wanted to minimize allocations and use an internal preallocated buffer, but I noticed that arrays are losing their capacity when its length is changed.

For example:

void main() {

        int[] a;
        a.reserve = 1024;

        void dump(in ref int[] b,size_t line = __LINE__) {
                import std.stdio;
                writeln(line, ": Buffer length = ", b.length, " capacity= ", b.capacity);
        }
        dump(a); // line 10
        a.length = 0;
        dump(a);
        a ~= [1,2,3];
        dump(a);
        a.length = 0;
        dump(a);
        a ~= [4,5,6];
        dump(a);
}

gives output:

10: Buffer length = 0 capacity= 2043
12: Buffer length = 0 capacity= 2043
14: Buffer length = 3 capacity= 2043
16: Buffer length = 0 capacity= 0
18: Buffer length = 3 capacity= 3

but I expected:

10: Buffer length = 0 capacity= 2043
12: Buffer length = 0 capacity= 2043
14: Buffer length = 3 capacity= 2043
16: Buffer length = 0 capacity= 2043
18: Buffer length = 3 capacity= 2043


Why is this happening, how to avoid it?


March 12, 2016
On Saturday, 12 March 2016 at 09:56:48 UTC, Uldis wrote:
>         dump(a); // line 10
>         a.length = 0;
>         dump(a);
>         a ~= [1,2,3];
>         dump(a);
>         a.length = 0;
>         dump(a);
>         a ~= [4,5,6];
>         dump(a);

I'll let others more knowledgeable explain why, but tack an a.assumeSafeAppend() after the length change and you'll get your desired behaviour.
March 12, 2016
> Why is this happening...?
For safety reasons. Your array can be shared between parts of application.
> ...how to avoid it?
https://dlang.org/library/object/assume_safe_append.html


March 12, 2016
On Saturday, 12 March 2016 at 09:56:48 UTC, Uldis wrote:
> Why is this happening, how to avoid it?

Details here: http://dlang.org/d-array-article.html

it is so one slice can never stomp over the contents of another slice when you append to it.

array.assumeSafeAppend() can override it.