February 03, 2009
On Tue, Feb 3, 2009 at 11:51 AM, nobody <somebody@somewhere.com> wrote:
> Would you also happen to know why the following gives an error?
>
>  arr[1] = arr[$-1];    // main.d(11): Error: cannot assign to static array

arr[1][] = arr[$-1][];

You cannot reassign what fixed-size array references point to, but you can copy their contents.

If this were an int[][], you would still probably want to do "arr[1][] = arr[$ - 1][]", since doing "arr[1] = arr[$ - 1]" would make arr[1] and arr[$ - 1] point to the same data; probably not what you would expect.
February 03, 2009
"Jarrett Billingsley" <jarrett.billingsley@gmail.com> wrote in message news:mailman.637.1233680615.22690.digitalmars-d-learn@puremagic.com...
> On Tue, Feb 3, 2009 at 11:51 AM, nobody <somebody@somewhere.com> wrote:
>> Would you also happen to know why the following gives an error?
>>
>>  arr[1] = arr[$-1];    // main.d(11): Error: cannot assign to static
>> array
>
> arr[1][] = arr[$-1][];
>
> You cannot reassign what fixed-size array references point to, but you can copy their contents.
>

Hm, I see.

> If this were an int[][], you would still probably want to do "arr[1][] = arr[$ - 1][]", since doing "arr[1] = arr[$ - 1]" would make arr[1] and arr[$ - 1] point to the same data; probably not what you would expect.

Well in this case I don't think it would be a problem, since right
afterwards i do
arr.length = arr.length - 1;
But I can see how I have to be careful with this :)


February 04, 2009
Please tell me when I got something wrong : )

>>>
>>> arr = arr[ 0 .. lowerBound ] ~ arr[ upperBound .. $ ];
>>>
>>
>> That's simple enough, but inefficient.
Because it loops over arr.length-2 and copies the pointers.
Will the compiler optimize by not copying the [0..lowerbound] part?
And will the compiler get that it can do
arr[x]=arr[x+difference]
for the [upperBound .. $] part
iso creating a temporary array (not doing in place is what this is called I
think)

>>
>> Something like this:
>>
>> import std.c.string; // or import tango.stdc.string;
>>
>> T[] erase(T)(ref T[] arr, size_t idx)
Where can I read about this variaidic type usage... looks awesome And, when do I need to use size_t?

>> {
>>    if(arr.length == 0)
>>        throw new Exception("FAILCOPTER");
>>
>>    if(idx < arr.length - 1)
>>        memmove(&arr[idx], &arr[idx + 1], T.sizeof * (arr.length - idx -
>> 1));
>>
>>    arr.length = arr.length - 1;
>>    return arr;
>> }
What you are doing here is the same as the above but forcing the two optimizations.

>
> Let's see if I understand memmove..
> The way it's used here, it copies the tail of an array onto that same
> array, only starting one index earlier, thus removing the undesired
> element?
> Neat.
>
> However I just realized that order does not matter in the array I'm using,
> so I guess I could use something like:
> arr[ind] = arr[$-1];
> arr.length = arr.length -1;
> Seeing how this only copies once, I'm guessing this is more efficient?
This will copy the pointer of the last element to the to-be-replaced element Will the GC actually delete the element with the unreferenced pointer arr[ind].ptr?



February 21, 2009
Tue, 3 Feb 2009 18:11:35 +0100, nobody wrote:

> "Jarrett Billingsley" <jarrett.billingsley@gmail.com> wrote in message news:mailman.637.1233680615.22690.digitalmars-d-learn@puremagic.com...
>> On Tue, Feb 3, 2009 at 11:51 AM, nobody <somebody@somewhere.com> wrote:
>>> Would you also happen to know why the following gives an error?
>>>
>>>  arr[1] = arr[$-1];    // main.d(11): Error: cannot assign to static
>>> array
>>
>> arr[1][] = arr[$-1][];
>>
>> You cannot reassign what fixed-size array references point to, but you can copy their contents.
>>
> 
> Hm, I see.
> 
>> If this were an int[][], you would still probably want to do "arr[1][] = arr[$ - 1][]", since doing "arr[1] = arr[$ - 1]" would make arr[1] and arr[$ - 1] point to the same data; probably not what you would expect.
> 
> Well in this case I don't think it would be a problem, since right
> afterwards i do
> arr.length = arr.length - 1;
> But I can see how I have to be careful with this :)

There's a gotcha here.  Reducing array length does not reallocate, and does not clean memory.  This may lead to dangling pointers and zombie memory.  Here's what I mean:

Let's have an array of four arrays of int.  I'll name them to simplify explanation:

int[] a, b, c, d; // suppose they're initialized
int[][] arr = [a, b, c, d];

Now delete b:

arr: [a, d, c], d

Above is a pseudo-code showing emory layout after one deletion.  Now delete the remaining d:

arr: [a, c], c, d

See, arr contains only a and c, but the memory chunk also references c and d.  GC doesn't know anything about arrays and scans whole chunks, so from GC's perspective the d array is still alive while you'd probably expect it be deallocated soon.

To avoid this bug you should zero the last element of your array before reducing its length:

arr[idx] = arr[$-1];
arr[$-1] = null;
arr.length = arr.length-1;
1 2
Next ›   Last »