Static Constructors

Steven Schveighoffer schveiguy at yahoo.com
Sat Oct 4 14:07:04 PDT 2008


"bearophile" wrote
> Steven Schveighoffer:
>> If you want the memory removed as soon as possible, you should zero out 
>> the
>> last element, otherwise, the GC will still think the element is being
>> pointed to:
>> data[n] = data[$-1];
>> data[$-1] = null;
>> data.length = data.length - 1;
>
> Really?? Is that another bug of dynamic arrays? I have assumed that 
> dynamic arrays do such things automatically.
> I do that in my collections, for example:
>
> ...
> void length(int newlen) {
>    if (newlen < 0 || newlen > this._length)
>        throw new ArgumentException("ArrayBuilder.length(newlen):"
>                                    " newlen < 0 || newlen > 
> ArrayBuilder.length");
>    static if (IsReferenceType!(T)) {
>        static if (IsStaticArray!(T)) {
>            T Tinit;
>            this.data[newlen .. this._length][] = Tinit;
>        } else {
>            this.data[newlen .. this._length] = T.init;
>        }
>    }
>    this._length = newlen;
> }
> ...
>
> If what you say is true, then it deserves a space on bugzilla and to be 
> fixed soon.

Setting data.length to one less is equivalent to:

data = data[0..$-1];

Which effectively leaves the pointer to the class untouched in the unused 
portion of the memory.  However, the memory is still valid in terms of the 
GC.  The GC scans the entire block for pointers, even if you aren't using 
all of the block.  That is why it always zeros out memory before giving it 
to you.

If setting the length to less than the original value did something special 
like zero out the now unused elements, then weird things would happen.

for example:

int[] data = [0,1,2,3,4].dup;

int[] dataslice = data[0..2];
dataslice.length = 1;

assert(data[1] == 1); // this would fail

-Steve 




More information about the Digitalmars-d-learn mailing list