Memory allocation in D (noob question)

Oskar Linde oskar.lindeREM at OVEgmail.com
Tue Dec 4 07:11:32 PST 2007


Steven Schveighoffer wrote:
> "Oskar Linde" wrote
>> mandel wrote:
>>> Steven Schveighoffer wrote:
>>> [..]
>>>> Now I create the valid array slices:
>>>>
>>>> int[] array3 = array1[$..$];
>>>> int[] array4 = array2[0..0];
>>>>
>>>> Note that both of these arrays are bit-for-bit identical (both have 0
>>>> length and the same ptr value).  Which one points to which piece of
>>>> memory?  How is the GC to decide which memory gets collected?
>>> I see the problem.
>>> The first possible solution that comes to my mind seeing this is to
>>> make array1[0..0] and array1[$..$] equal.
>>> array1[$..$] could point to the begin of the array.
>>> Since the slice length is null, it shouldn't matter - would it?
>> Appending to a (empty or not) array slice starting at the start of an 
>> allocated block appends in-place rather than allocate a new array. This is 
>> the reason
>>
>> while(x)
>>   a ~= b;
>>
>> can be reasonably efficient.
> 
> Hm... I think you are slightly incorrect.  I think the array is appended to 
> in place ONLY if the data after the slice is unallocated.  In this case, it 
> would be allocated, so the array would be re-allocated elsewhere.

Try this:

         char[] ab = "ab".dup;
         char[] a = ab[0..1];
         a ~= "c";
         writefln("ab = ",ab);

>> So appending to the [$..$] array would (without padding) mean that you 
>> corrupt the following array.
> 
> I think this is incorrect for the reasons I stated above.  An allocated 
> block should never be re-assigned to another array.

See my example above. The allocated block is deduced from the slice 
.ptr. If the pointer points at the start of another array, DMD would 
have no way of knowing it isn't a slice of that other array.

> Maybe I am wrong, but I think mandel might have a possible solution to this 
> problem.  If you slice an empty array (or even allocate an empty array), set 
> the pointer to null.  No reason to allocate an empty array, and no reason 
> you need to keep memory around for it.  If you append to it, it's going to 
> be like appending to an init array anyways.  That would also make null 
> comparisons more consistent like:
> 
> int[] array1 = array2[0..0];
> 
> if(array1 is null) // evaluates to true!
> ...

There are several cases where it is useful to retain the pointer when 
the array is of zero length, for example a zero length regexp 
sub-expression match.

It used to be the case that setting a slice length to 0 (via the length 
property) made the pointer null as well. That changed a while ago.

-- 
Oskar



More information about the Digitalmars-d mailing list