Tue, 3 Feb 2009 18:11:35 +0100, nobody wrote:
> "Jarrett Billingsley" wrote in message
> news:mailman.637.1233680615.22690.digitalmars-d-le...@puremagic.com...
>> On Tue, Feb 3, 2009 at 11:51 AM, nobody 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;