16

in this example

procedure foobar;
var tab:array of integer;
begin
  setlength(tab,10);
end;

is the array destroyed or the memory is leaking?

8
  • While it may not leak, you really should free your own variables. Do the SetLength(tab, 0); it's one extra line. If your worried about it then wrap it in a try/finally block. Commented Jun 25, 2010 at 2:42
  • 2
    I cannot endorse that advice, @Ryan. Do you manually clear all your string variables, too? When I see code assigning values to variables that are never used again, it tells me the programmer doesn't really understand how the language works. In particular, the compiler already puts a try-finally block around the function body to ensure that the dynamic-array variable gets cleaned up. Putting in one of your own is overkill. Commented Jun 25, 2010 at 12:29
  • @Ryan, that's just wrong. The call to SetLength is a total waste, both of keystrokes and an unnecessary function call at runtime. Dynamic arrays are managed by the compiler, and will be freed automatically when they go out of scope. Commented Jun 25, 2010 at 13:09
  • 2
    The memory for the array is freed by the compiler, but an array of objects that are referenced using a dynamic array must still be freed if that array "owns" them conceptually. Change the above code from "tab:array of integer" to "tab:array of TObject" and suddenly you have a leak possibility. Commented Jun 25, 2010 at 13:58
  • 1
    @Ryan, assigning nil, calling Finalize, and setting the length to zero are all equivalent ways of releasing a dynamic array. And they're all unnecessary when the array's going out of scope because that's yet another way to release a dynamic array. The help doesn't say so explicitly because it's implied by stating the dynamic arrays use the same reference-counting technique that long strings use. Defensive programming is fine, but it's better when you're defending against things that might actually happen. Commented Jun 25, 2010 at 16:24

2 Answers 2

16

The memory is freed. (That is, no memory leak!)

Sign up to request clarification or add additional context in comments.

3 Comments

Elements are also freed if those are managed by the compiler too (dyn arrays, strings, intf, records with such types and so on).
For "tab:array of Integer", everything is freed. For "tab:array of TObject", or any other class, you must free the Objects yourself.
True, @Warren, but that has nothing to do with the array. The same advice applies to an ordinary scalar. Objects need to be freed; integers don't.
1

The array is automatically freed, but I've seen obscure cases where it isn't for some reason. I solved it by setting the array to nil.

4 Comments

There are only two reasons why it wouldn't be freed. Either you're doing something scary with pointers that messes up the reference counting, or the array is owned by an object or record which is also leaking.
I know, somehow there was something else causing it not to auto-free. I wish I still had the example to prove it! But I don't.
That would be a bug in the compiler's code-gen. Or maybe it was a threadvar? The help clearly state that managed type used as threadvars won't free themselves automatically and you need to do so manually.
It wasn't a threadvar, I've never used them. It was just an array of doubles that was a field of a class, FastMM revealed the leak. It was in Delphi 7.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.