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