PDA

View Full Version : SetLength



Viro
18-02-2003, 06:46 PM
It is my understanding that SetLength creates an array that is managed by the garbage collector. My questions are :-

If I create an array of double's with SetLength, I won't have to call any function to deallocate it, right?

When is the array deallocated? After it goes out of scope? Or like the Java VM, which is indeterminate?

Thanks.

Crisp_N_Dry
18-02-2003, 08:24 PM
I think but can't be certain that you must deallocate the array when done by set the length to 0, but I can't be sure that it isn' t deallocated when the application shuts down when using the VCL. I remember, while using the API and a dynamic array that after a heavy afternoons compiling my machine filled up 256mb of memory because I hadn't been deallocating some hefty map array but that was without the VCL and they behave slightly differently when it come to destroying stuff. I wonder if AliMonster knows, he's down with all that.

Useless Hacker
18-02-2003, 09:10 PM
...

Alimonster
18-02-2003, 09:14 PM
I'm pretty certain that dynamic arrays get disposed when they go out of scope - they're handled in the same way as strings, and you don't see many people worrying about deallocating strings. :cat:

Dynamic arrays are ref-counted, so it seems very likely that they get squished at the end of scope, and very unlikely that they'll be garbage collected at a non-deterministic time.

Of course, there are a couple of ways (maybe three) to manually kill the memory if you're feeling paranoid: set the array var to nil, pass it to the Finalize procedure, or SetLength to 0 (which I think does a deallocation, not that it matters too much). I've got into the habit of manually setting all my vars to nil/0, but that's just extra-safety for a larger project that I have on the backburner. It should be safe to leave 'em alone.

The only thing to remember, and the thing that may have bitten you Crisp_N_Dry: clearing up the memory for the dynamic array won't clear anything dynamic that's stored inside the array's elements! (e.g. GetMem'd pointers or created classes). I think.. You'd want to clear the array elements by looping over them in the usual fashion - for i := Low(whatever) to High(Whatever) do FreeMem(Whatever[i]); // or equivalent squishing-stored-dynamic-mem.

Here's a relevant link: http://www.info.umfcluj.ro/resurse/Carti/Delphi/Charlie_Calverts_Delphi_4_Unleashed/0672312859/ch02/062-065.html#Heading22

Anecdotal evidence, anyway - Charlie Calvert doesn't worry about deallocating the dynamic arrays, and I trust his judgement a lot. :) Also, two quotes from the help:


Dynamic-array variables are implicitly pointers and are managed by the same reference-counting technique used for long strings

...and:


This memory is allocated on the heap, but its management is entirely automatic and requires no user code

If dynamic arrays use the same mechanism as long strings, and long strings are managed automatically, then [insert_conclusion_here].

Alimonster
18-02-2003, 09:31 PM
Yes, you do have to dealocate it. To do this you would do:
SetLength(YourArray, 0);
Whether you're using the VCL or not makes no difference, since the array is not a VCL component. Delphi does not manage dynamic arrays with garbage collection, it will only be deallocated when you do so, or possibly when the application closes.
Delphi applies slightly different rules to some objects, doing work behind the scenes: Interfaces, dynamic arrays and strings. What's life without a few exceptions to the rule, eh? ;) I might be wrong in my assertion that the stuff is cleaned up; maybe a quick test cradle is in order to provide a conclusive answer.

Useless Hacker
18-02-2003, 10:15 PM
Looks like I was talking crap as usual!

From the Delphi help:

Dynamic-array variables are implicitly pointers and are managed by the same reference-counting technique used for long strings. To deallocate a dynamic array, assign nil to a variable that references the array or pass the variable to Finalize; either of these methods disposes of the array, provided there are no other references to it. Dynamic arrays are automatically released when their reference-count drops to zero. Dynamic arrays of length 0 have the value nil. Do not apply the dereference operator (^) to a dynamic-array variable or pass it to the New or Dispose procedure.

Viro
18-02-2003, 11:16 PM
Thanks for the info guys. You are the best.