Thread overview
Using .length returns incorrect number of elements
Aug 19, 2018
QueenSvetlana
Aug 19, 2018
Chris M.
Aug 19, 2018
Chris M.
Aug 19, 2018
QueenSvetlana
Aug 19, 2018
Chris M.
Aug 19, 2018
Simen Kjærås
August 19, 2018
When using the .length property of a dynamic array why does it return the incorrect number of elements after I use the appender?

import std.stdio;
import std.array : appender;

void main()
{
    //declaring a dynamic array
    int [] arrayofNumbers;
    //append an element using the ~= syntax
    arrayofNumbers ~= 1;
    arrayofNumbers ~= 2;
    //print the array
    writeln(arrayofNumbers);

    //Using appender
    auto appendNumber = appender(arrayofNumbers);
    appendNumber.put(10);
    writeln(appendNumber.data);

    writeln(arrayofNumbers.length);

}

Output:

[1, 2]
[1, 2, 10]
2  --- > Should be 3
August 19, 2018
On Sunday, 19 August 2018 at 15:44:07 UTC, QueenSvetlana wrote:
> When using the .length property of a dynamic array why does it return the incorrect number of elements after I use the appender?
>
> import std.stdio;
> import std.array : appender;
>
> void main()
> {
>     //declaring a dynamic array
>     int [] arrayofNumbers;
>     //append an element using the ~= syntax
>     arrayofNumbers ~= 1;
>     arrayofNumbers ~= 2;
>     //print the array
>     writeln(arrayofNumbers);
>
>     //Using appender
>     auto appendNumber = appender(arrayofNumbers);
>     appendNumber.put(10);
>     writeln(appendNumber.data);
>
>     writeln(arrayofNumbers.length);
>
> }
>
> Output:
>
> [1, 2]
> [1, 2, 10]
> 2  --- > Should be 3

auto appendNumber = appender(arrayofNumbers);

This returns a separate object. You probably meant to put this for the last line

writeln(appendNumber.length);
August 19, 2018
On Sunday, 19 August 2018 at 15:49:18 UTC, Chris M. wrote:
> On Sunday, 19 August 2018 at 15:44:07 UTC, QueenSvetlana wrote:
>> [...]
>
> auto appendNumber = appender(arrayofNumbers);
>
> This returns a separate object. You probably meant to put this for the last line
>
> writeln(appendNumber.length);

Whoops

writeln(appendNumber.data.length);

https://run.dlang.io/is/4aNx1l
August 19, 2018
On Sunday, 19 August 2018 at 15:53:25 UTC, Chris M. wrote:
> On Sunday, 19 August 2018 at 15:49:18 UTC, Chris M. wrote:
>> On Sunday, 19 August 2018 at 15:44:07 UTC, QueenSvetlana wrote:
>>> [...]
>>
>> auto appendNumber = appender(arrayofNumbers);
>>
>> This returns a separate object. You probably meant to put this for the last line
>>
>> writeln(appendNumber.length);
>
> Whoops
>
> writeln(appendNumber.data.length);
>
> https://run.dlang.io/is/4aNx1l

New to d programming here :D Bare with me.

The object that is returned by appendNumber.data is an array reflecting the elements I added using appendNumber correct? So I would have the call length on appendNumber.data instead of the original array?
August 19, 2018
On Sunday, 19 August 2018 at 16:03:06 UTC, QueenSvetlana wrote:
> On Sunday, 19 August 2018 at 15:53:25 UTC, Chris M. wrote:
>> On Sunday, 19 August 2018 at 15:49:18 UTC, Chris M. wrote:
>>> On Sunday, 19 August 2018 at 15:44:07 UTC, QueenSvetlana wrote:
>>>> [...]
>>>
>>> auto appendNumber = appender(arrayofNumbers);
>>>
>>> This returns a separate object. You probably meant to put this for the last line
>>>
>>> writeln(appendNumber.length);
>>
>> Whoops
>>
>> writeln(appendNumber.data.length);
>>
>> https://run.dlang.io/is/4aNx1l
>
> New to d programming here :D Bare with me.
>
> The object that is returned by appendNumber.data is an array reflecting the elements I added using appendNumber correct? So I would have the call length on appendNumber.data instead of the original array?

Yes, the .data field gives the array you're working on.
August 19, 2018
On Sunday, 19 August 2018 at 16:03:06 UTC, QueenSvetlana wrote:
> On Sunday, 19 August 2018 at 15:53:25 UTC, Chris M. wrote:
>> On Sunday, 19 August 2018 at 15:49:18 UTC, Chris M. wrote:
>>> On Sunday, 19 August 2018 at 15:44:07 UTC, QueenSvetlana wrote:
>>>> [...]
>>>
>>> auto appendNumber = appender(arrayofNumbers);
>>>
>>> This returns a separate object. You probably meant to put this for the last line
>>>
>>> writeln(appendNumber.length);
>>
>> Whoops
>>
>> writeln(appendNumber.data.length);
>>
>> https://run.dlang.io/is/4aNx1l
>
> New to d programming here :D Bare with me.
>
> The object that is returned by appendNumber.data is an array reflecting the elements I added using appendNumber correct? So I would have the call length on appendNumber.data instead of the original array?

I suggest reading the D tour's page on arrays:
https://tour.dlang.org/tour/en/basics/arrays

In short, D arrays (more correctly called slices) are structs that look like this:

struct Slice(T) {
    T* ptr;
    size_t length;
}

As the name Slice indicates, it represents a slice of memory, with a beginning address and a length. If you have two int[] instances (let's call them A and B) that point to the same data, they have their own copy of the ptr and length fields, and changing the value of a field in A will not change the corresponding field in B.

When you append to A, what's happening* is the length is increased, and the appended data is written to the end of the memory pointed to. B does not see this, since it only looks at the first <length> elements of that block.

--
  Simen

* Plus some checking of the length of the block of memory it's pointing to, and possible reallocation if the block isn't big enough.