October 04, 2008 Re: Static Constructors | ||||
---|---|---|---|---|
| ||||
Posted in reply to bearophile | 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 Re: Static Constructors | ||||
---|---|---|---|---|
| ||||
Posted in reply to Saaa | 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 Re: Static Constructors | ||||
---|---|---|---|---|
| ||||
Posted in reply to Saaa | 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 Re: Static Constructors | ||||
---|---|---|---|---|
| ||||
Posted in reply to Saaa | "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 Re: Static Constructors | ||||
---|---|---|---|---|
| ||||
Posted in reply to Saaa | "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 Re: Static Constructors | ||||
---|---|---|---|---|
| ||||
Posted in reply to Saaa | 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 Re: Static Constructors | ||||
---|---|---|---|---|
| ||||
Posted in reply to 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;
>
> -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 Re: Static Constructors | ||||
---|---|---|---|---|
| ||||
Posted in reply to Saaa | Thanks! I love these newsgroups :) |
October 04, 2008 Re: Static Constructors | ||||
---|---|---|---|---|
| ||||
Posted in reply to Steven Schveighoffer | 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 Re: Static Constructors | ||||
---|---|---|---|---|
| ||||
Posted in reply to Saaa | 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. |
Copyright © 1999-2021 by the D Language Foundation