Thread overview
Re: cloning arrays
Sep 10, 2016
Jonathan M Davis
Sep 12, 2016
Russel Winder
Sep 12, 2016
ag0aep6g
Sep 12, 2016
Jonathan M Davis
September 10, 2016
On Saturday, September 10, 2016 17:58:37 Russel Winder via Digitalmars-d-learn wrote:
> What is the idiomatic way of cloning an array?
>
> I had wondered about x.dup but am now worried this is not creating a shallow copy.

dup creates an array with mutable elements that are copies of what was in the original array. How deep a copy that is depends on the type. It does exactly as deep a copy as simply copying the element would do. e.g.

auto e = arr[4];

So, unless postblit constructors are involved, then it's not going to be doing any deep copying, and if a postblit constructor that does a deep copy is involved, then any other copying you'd do with it would be deep too unless you explicitly bit-blitted it rather than copying it, and that's usually a bad idea.

- Jonathan M Davis

September 12, 2016
On Sat, 2016-09-10 at 15:54 -0700, Jonathan M Davis via Digitalmars-d- learn wrote:
> […]
> 
> dup creates an array with mutable elements that are copies of what
> was in
> the original array. How deep a copy that is depends on the type. It
> does
> exactly as deep a copy as simply copying the element would do. e.g.
> 
> […]

Which raises the question of whether:

	x[]

and

	x.dup

have the same result.

-- 
Russel. ============================================================================= Dr Russel Winder      t: +44 20 7585 2200   voip: sip:russel.winder@ekiga.net 41 Buckmaster Road    m: +44 7770 465 077   xmpp: russel@winder.org.uk London SW11 1EN, UK   w: www.russel.org.uk  skype: russel_winder

September 12, 2016
On 09/12/2016 08:56 AM, Russel Winder via Digitalmars-d-learn wrote:
> Which raises the question of whether:
>
> 	x[]
>
> and
>
> 	x.dup
>
> have the same result.
>

No. x[] is a nop for dynamic arrays. Only the array struct (pointer and length) gets copied, as it always does. x.dup copies the array's elements to a new location.
September 12, 2016
On Monday, September 12, 2016 07:56:26 Russel Winder via Digitalmars-d-learn wrote:
> On Sat, 2016-09-10 at 15:54 -0700, Jonathan M Davis via Digitalmars-d-
>
> learn wrote:
> > […]
> >
> > dup creates an array with mutable elements that are copies of what
> > was in
> > the original array. How deep a copy that is depends on the type. It
> > does
> > exactly as deep a copy as simply copying the element would do. e.g.
> >
> > […]
>
> Which raises the question of whether:
>
>   x[]
>
> and
>
>   x.dup
>
> have the same result.

They don't. For dynamic arrays,

auto y = x;

and

auto y = x[];

are identical save for constness. The first one results in y being a dynamic array referring to exactly the same memory as x with exactly the same constness, whereas the second results in y referring to the same memory, but it's a tail-const version of x. e.g.

    auto x = cast(immutable)[1, 2, 3, 4];
    auto y = x;
    auto z = x[];
    static assert(is(typeof(x) == immutable(int[])));
    static assert(is(typeof(y) == immutable(int[])));
    static assert(is(typeof(z) == immutable(int)[]));

But regardless of the constness, x, y, z refer to exactly the same memory. No memory is allocated, and none of the elements are copied.

If you do something like

y[] = x[];

then that would be equivalent to

y[0 .. $] = x[0 .. $];

and it would copy all of the elements of x into y, but it would require that x and y be the same length, and it would not allocate any memory. It's just copying the elements.

dup specifically allocates a new buffer, copies each of the elements of the original array into that buffer, and then returns a dynamic array which is a slice of that buffer referring to those elements. It does essentially the same thing as

auto y = new int[](x.length);
y[] = x[];

except that that default-initializes all of the elements in y first, and then copies over them, whereas dup should just copy them without doing the default initialization first.

- Jonathan M Davis