dynamic array .length vs .reserve - what's the difference?
Steven Schveighoffer
schveiguy at gmail.com
Thu Jul 30 16:55:35 UTC 2020
On 7/30/20 11:58 AM, wjoe wrote:
> I just stumbled upon code like this:
>
> struct Foo(T)
> {
> T[] b;
>
> this(int n)
> {
> b.reserve(n);
> b.length = n;
> }
> }
>
> ..reserve looks redundant.
It is, in this case. Reserve will extend the allocated length to n, but
not adjust the slice, and setting the length will adjust the slice and
consume that data from the block. Just setting length has the same effect.
>
> The docs are explaining .length nicely, however lack any specifics about
> reserve.
>
> Changing the length of an array may relocate and copy. New items are
> initialized with T.init - is that true for both length and reserve ?
reserve preallocates data for use in appending, but does not alter the
length of the specified array.
It's like saying, "I'm going to append enough elements to this array so
the total length is N." It's very much tied to appending.
Note that reserve may do nothing, if there is already at least N
elements available.
> Also there's .capacity - is that equivalent to reserve ?
Capacity tells you how many total elements the current reserved space
can hold. If the array is not appendable, then this returns 0.
> Another curiosity I noticed is that the docs say that the runtime tries
> to resize in place, however:
>
> b = b[0..$-1]; if length==1 seems to collect the memory at once because
> if it's immediately followed by b.length = 1; or b ~= someT; b.ptr
> points to a new address.
> Why ?
Because you would be overwriting the data already in the array.
For example:
auto a = b;
b = b[0 .. $-1];
b ~= someT;
If that last line is done in-place, then it overwrites a[$-1].
If you know that it's OK to do this, then you should call
assumeSafeAppend on the array (which will adjust the "used" space down
to the current array).
> I know that b=b[0..0]; is equivalent to b = null;
No, if slicing b to b[0 .. 0], b.ptr does not change. b = null sets the
pointer to null. In the former case, if you called assumeSafeAppend on
it, then it could append in-place at that point. With the null pointer,
it would reallocate.
-Steve
More information about the Digitalmars-d-learn
mailing list