Why is dynamic array length required here?

Mike Parker aldacron at gmail.com
Fri Oct 19 05:46:36 UTC 2018


On Friday, 19 October 2018 at 02:04:37 UTC, Samir wrote:
>
> I would have thought that since this is a dynamic array, I 
> don't need to pre-assign its length.
>
> Thanks


Just to expand on the previous answers, a dynamic array 
declaration with no initializer is an empty array:

int[] arr;
assert(arr.length == 0);

No memory has been allocated to store any elements. Appending 
elements will allocate memory. In fact, the runtime will allocate 
more than needed so that it doesn't have to allocate on each 
append.

arr ~= 1;
assert(arr.length == 1);
writeln(arr.capacity);

When the capacity is 0, the next append will trigger another 
allocation. The reserve function can be used to allocate enough 
memory for a number of elements, but the array will still be 
empty:

int[] arr;
arr.reserve(100);
assert(arr.length == 0);
writeln(arr.capacity);

Now 100+ elements can be appended without triggering an 
allocation.

Setting the length directly as Ali's example does means that not 
only is the required memory allocated, but also that the array is 
not empty.

int[] arr;
arr.length = 100;
assert(arr.length == 100);
writeln(arr.capacity);

And now the array can elements can be written to directly via the 
index operator, and a pointer to each element can be referenced 
as it is in the call to readf.

Note that it's still possible to write elements directly to a 
dynamic array without the append operator after memory has been 
reserved, but it completely bypasses the runtime.

void main() {
     int[] myArray;

     myArray.reserve(10);
     foreach(i; 0 .. 10) {
         *(myArray.ptr + i) = i;
     }

     assert(myArray == []);
     assert(myArray.length == 0);

     foreach(i; 0 .. 10) {
         writeln(*(myArray.ptr + i));
     }
}

This is essentially treating myArray.ptr as a C array, with no 
bounds checking and no automatic memory management. Here be 
dragons.


More information about the Digitalmars-d-learn mailing list