September 01, 2015
On 09/01/2015 12:43 AM, qznc wrote:
> On Monday, 31 August 2015 at 22:03:07 UTC, jmh530 wrote:
>> In general, I find myself very easily getting mixed up by the syntax
>> of the static vs. dynamic arrays. For instance, compare
>> int[] x = new int[3];
>> int[3] y = new int[3];
>> auto z = new int[3];
>> x and y are obviously dynamic and static arrays, respectively.
>> However, my initial guess on z is that is like y, a static array on
>> the heap. But that is wrong. It's actually like x. Easy to get confused.
>
> In general, "new" means heap allocation.
>
> I wonder about the initialization of y. Maybe it creates a temporary
> dynamic array on the heap and then copies it to the static array on the
> stack?

Seems to be so:

import std.stdio;

void main()
{
    int[] x = new int[3];
    int[3] y = new int[3];
    auto z = new int[3];

    writeln(x.ptr);
    writeln(y.ptr);
    writeln(z.ptr);
}

y's elements are on the stack:

7F1375618200
7FFF091A9910
7F1375618220

Ali

September 01, 2015
On Monday, August 31, 2015 21:36:17 John Colvin via Digitalmars-d-announce wrote:
> On Monday, 31 August 2015 at 21:29:09 UTC, anonymous wrote:
> > On Monday 31 August 2015 23:09, Minas Mina wrote:
> >
> >> I have started a series of tutorials in D.
> >>
> >> This is my latest blog post, which is about dynamic arrays: http://minas-mina.com/2015/08/31/dynamic-arrays/
> >>
> >> Constructive criticism is welcome.
> >
> > "Dynamic arrays are allocated on the garbage collected heap" "Dynamic arrays can be sliced"
> >
> > These are not wrong, but maybe a little bit misleading.
> >
> > Static arrays and pointers can be sliced, too. And a slice of a static array or pointer is ... dramatic pause ... a dynamic array that doesn't necessarily refer to the GC heap.
>
> I prefer the term "slice" to dynamic array. Because it's an unfamiliar term it helps prevent confusion for people who are used to what other languages call dynamic arrays.

Per the spec, T[] is a dynamic array no matter what backs it. And slice is a _heavily_ overloaded term in D - e.g. you slice a range, and you get another range, not necessarily a dynamic array. If you slice a container, you get a range, not a container or a dynamic array.

Steven's article uses the wrong terminology (at least as for as the spec is concerned), which I wish it didn't, since I think that that causes other kinds of confusion, and it has led folks to use the term slice when the official term is dynamic array, but his article has gone a long way to explaining D's dynamic arrays to people, and we're very much better off for it.

But there is no non-overloaded term to use here, and I think that folks get overly hung up over the difference between T[] as a struct and the memory that it refers to. The semantics of the code generally don't care what's backing the dynamic array. It's a dynamic array regardless of what memory backs it, and you can do the same operations on it either way. What changes is the lifetime of the memory that it refers to. Everything else is the same.

All of the operations which involve allocation or checking for free space for the dynamic array to grow into work regardless of whether the memory that it refers to is GC-allocated or not. And since you can't know whether the memory is going to be reallocating when appending without checking the capacity, the fact that any memory that isn't GC-allocated is guaranteed to reallocate when appending doesn't change much. A GC-backed dynamic array could have end up with reallocated memory just as easily. You have to check the capacity to know. And the semantics are really the same whether the memory backing the dynamic array is GC-allocated or not.

So really, what it comes down to is how the lifetime of a dynamic array's memory is managed, and it's _not_ the dynamic array that's doing the managing regardless of what memory is backing it. If it was GC-allocated, then it's the GC, whereas if it were malloced, then your code needs to keep track of it elsewhere, and if it was sliced from a static array, then you need to make sure that the dynamic array doesn't outlive the static one. So, if the dynamic array is referring to non-GC allocated memory, then you need to be careful in order to make sure that the dynamic array doesn't outlive the memory that it refers to, but all of the operations are the same either way.

So, I honestly think that the focus on the GC-allocated buffers that dynamic arrays usually refer to actually confuses people at least some of the time. If you want to manage the memory efficiently, then you need to understand how that works, and you need to understand which operations will talk to the GC and which _might_ cause allocations so that you can avoid unnecessary communication with the GC and avoid having code that assumes that two dynamic arrays refer to the same memory when they don't. But the dynamic arrays themselves really don't care what backs them, and aside from making sure that you manage the lifetime of that memory properly when it's not GC-allocated, the code that uses dynamic arrays really doesn't care what's backing them.

- Jonathan M Davis

1 2
Next ›   Last »