Thread overview
Strict capacity of array
Dec 13, 2013
FreeSlave
Dec 13, 2013
Ali Çehreli
Dec 13, 2013
Marco Leise
Dec 13, 2013
FreeSlave
Dec 14, 2013
Marco Leise
December 13, 2013
Suppose some class contains slice (dynamic array) as data member. Constructor takes integer value that defines the size of data should be allocated. After object was constructed size of slice never changes by design.

Dynamic arrays are allocated with extra space that we can know from 'capacity' property. But how can I allocate exactly as much elements as I want? Because in case described above we don't need extra space.

I know it's possible to use malloc in constructor and free in destructor. But what if I want to expose inner slice by shallow copy (i.e. by copying pointer and size, but not underlined data) then use it just like usual dynamic array whose lifetime does not depend on lifetime of an object it belongs and is managed by GC?
December 13, 2013
On 12/13/2013 10:47 AM, FreeSlave wrote:

> Suppose some class contains slice (dynamic array) as data member.
> Constructor takes integer value that defines the size of data should be
> allocated. After object was constructed size of slice never changes by
> design.
>
> Dynamic arrays are allocated with extra space that we can know from
> 'capacity' property. But how can I allocate exactly as much elements as
> I want? Because in case described above we don't need extra space.

If it is not maintained by you, you can never be sure. There is arr.reserve(N) that ensures that much room without placing .init elements on the space.

> I know it's possible to use malloc in constructor and free in
> destructor. But what if I want to expose inner slice by shallow copy
> (i.e. by copying pointer and size, but not underlined data) then use it
> just like usual dynamic array whose lifetime does not depend on lifetime
> of an object it belongs and is managed by GC?

That is supported:

    auto slice = rawPtr[0..number_of_elements];

Ali

December 13, 2013
Am Fri, 13 Dec 2013 19:47:34 +0100
schrieb "FreeSlave" <freeslave93@gmail.com>:

> Suppose some class contains slice (dynamic array) as data member. Constructor takes integer value that defines the size of data should be allocated. After object was constructed size of slice never changes by design.
> 
> Dynamic arrays are allocated with extra space that we can know from 'capacity' property. But how can I allocate exactly as much elements as I want? Because in case described above we don't need extra space.

There was a recent discussion about the capacity of a dynamic
array that is allocated with a known size (e.g. new int[](25)).
I think the extra space comes from the way the GC allocates
blocks of memory in preset sizes. Actually a malloc implementation
could also have some hidden overallocation.

> I know it's possible to use malloc in constructor and free in destructor. But what if I want to expose inner slice by shallow copy (i.e. by copying pointer and size, but not underlined data) then use it just like usual dynamic array whose lifetime does not depend on lifetime of an object it belongs and is managed by GC?

Have you tried this?:

import core.memory;
int[] data = (cast(int*)GC.malloc(size * int.sizeof, GC.BlkAttr.NO_SCAN))[0 .. size];

-- 
Marco

December 13, 2013
Thanks for answers.

On Friday, 13 December 2013 at 19:35:01 UTC, Marco Leise wrote:
> Have you tried this?:
>
> import core.memory;
> int[] data = (cast(int*)GC.malloc(size * int.sizeof, GC.BlkAttr.NO_SCAN))[0 .. size];

Did you mean GC.BlkAttr.NONE maybe? If I get it right GC.BlkAttr.NO_SCAN means that memory will never be collected by GC (i.e. it's just like C malloc), but I've asked for opposite.
December 14, 2013
Am Fri, 13 Dec 2013 21:02:58 +0100
schrieb "FreeSlave" <freeslave93@gmail.com>:

> Thanks for answers.
> 
> On Friday, 13 December 2013 at 19:35:01 UTC, Marco Leise wrote:
> > Have you tried this?:
> >
> > import core.memory;
> > int[] data = (cast(int*)GC.malloc(size * int.sizeof,
> > GC.BlkAttr.NO_SCAN))[0 .. size];
> 
> Did you mean GC.BlkAttr.NONE maybe? If I get it right GC.BlkAttr.NO_SCAN means that memory will never be collected by GC (i.e. it's just like C malloc), but I've asked for opposite.

You got it wrong :)
NO_SCAN means that the memory block you allocate isn't
scanned for _more_ references to stuff on the GC heap.
If you use the allocated memory as an int[] it doesn't make
sense to look into it for pointers to other memory blocks in
order to mark them alive. (The GC is a mark&sweep algorithm.)
If you actually store class pointers or similar instead of ints
then drop that attribute.

-- 
Marco