October 04, 2008
Thanks, from this I'd rather delete them manually :)

>
> The GC deletes an object (usually, but sometimes it doesn't do it because it's not a precise GC) when there are no references to/from it.
>
> So if you keep it just inside an array, and it has no inbound references, and you remove it somehow (for example overwriting it with the last item of the array and then reducing the length of the array by 1), the GC loses the only reference to that objects, and deallocates it.
>
> Note the same thing happens in most languages/systems that have a GC.
>
> If your object manages some other resources beside its memory, for example an open file, you have to close it inside the destructor of your object. If the not precise GC keeps a spurious (wrong) reference to your object (because somewhere an int value looks like a pointer to the object memory block), then you are in troubles...
>
> Bye,
> bearophile


October 04, 2008
Saaa Wrote:

> Thanks, from this I'd rather delete them manually :)

No, deleting them manually is un-D-tonic :-)
In most situations you let the GC do its work.

Bye,
bearophile
October 04, 2008
Can I do something like this, or should I use the static constructor for
this?
If so, how should I set the first parameter:size ?

Fruits fruit[];


class Fruit
{
this( parameters )
{
fruit[].length=fruit[].length+1;
fruit[$-1]=this;
}
 ..
void stuff()
{
}
..
}

new fruit( .. );
new fruit( .. );

foreach (Fruit f; fruit)
{
f.stuff();
}


October 04, 2008
"Saaa" <empty@needmail.com> wrote in message news:gc8314$24e0$1@digitalmars.com...
>
>>
>> First one allocates new memory block.
>> Second one attempts to erase an element in-place. Dupping, however,
>> allocates new memory, too.
>> The best solution would be as follows:
>>
>> void eraseNth(ref T[] data, int n) {
>>     data[n] = data[$-1];
>>     data.length = data.length - 1;
>> }
>
> Yay, thats how I do it :)

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;

-Steve


October 04, 2008
"Saaa" wrote
> Can I do something like this, or should I use the static constructor for
> this?
> If so, how should I set the first parameter:size ?
>
> Fruits fruit[];

typo, and you are using C-style array syntax (which works, but is discouraged).  This should be:

Fruit[] fruit;

Means, 'I declare an array of Fruit called fruit'

>
>
> class Fruit
> {
> this( parameters )
> {
> fruit[].length=fruit[].length+1;
> fruit[$-1]=this;


Don't do the [] operator, I think this may create a temporary array struct, and would not affect the global variable at all:

fruit.length = fruit.length + 1;

But instead of this, it's probably better to write:

fruit ~= this;

Which does all that work for you :)

> }
> ..
> void stuff()
> {
> }
> ..
> }
>
> new fruit( .. );
> new fruit( .. );
>
> foreach (Fruit f; fruit)
> {
> f.stuff();
> }

This should work, but be aware that it's not thread safe if you are using multiple threads.

-Steve


October 04, 2008
Saaa:
> foreach (Fruit f; fruit)
> {
> f.stuff();
> }

Note that often this is enough:

foreach (f; fruit)
    f.stuff;

But I generally put the parentheses:

foreach (f; fruit)
    f.stuff();

Bye,
bearophile
October 04, 2008
> 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;
>
> -Steve

Because the GC sees all allocated memory as used and an array doesn't deallocate memory when made smaller?

Or just delete it :)


October 04, 2008
Thanks!
I love these newsgroups :)


October 04, 2008
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.

Bye,
bearophile
October 04, 2008
What would happen here?
Would the GC delete the newly made instances as there is no reference to it?

Fruits fruit[];
class Fruit
{
this( parameters )
{

}
..
void stuff()
{
}
 ..
}

new fruit( .. );
//or can this only be called if there is an static constructor?
new fruit( .. );

foreach (f; fruit)
  f.stuff();
//fruit is empty.