4
type Tmyclass = class(TObject)
  somearray: array of TSometype
  FBool: Boolean;
  Fint: Integer;
  Fstr: string;
  constructor Create;
  destructor Destroy; override;
end;

implementation

constructor Tmyclass.Create;
begin
  inherited;
  SetLength(somearray,0); //is this needed?
end;

destructor TmyClass.Destroy;
begin
  SetLength(somearray,0); //this IS needed!
  inherited;
end;

Also what types are initialized on creation? For example what I declared in the class. is FBool guranteed to be false? is FInt guranteed to be 0? is Fstr guranteed to be ''?

What about local? Only strings?

I use Delphi XE.

1

5 Answers 5

16

Dynamic arrays are managed types and so are always initialized to nil, equivalent to SetLength(..., 0). You never need to do this.

The only time you can get caught out is when you are returning a dynamic array from a procedure as a function return value. In fact a function return value is in fact just an implicit var parameter.

Consider the following code:

function Foo: string;
begin
  Result := Result + 'X';
end;

var
  i: Integer;

begin
  for i := 1 to 5 do
    Writeln(Foo);
  Writeln(Foo);
  Writeln(Foo);
end;

Output

X
XX
XXX
XXXX
XXXXX
X
X

What's going on here is that the compiler, as an optimization is electing not to re-initialize the implicit local variable inside the loop.

This can catch you out from time to time so I recommend setting to nil return values that are dynamic arrays, strings, interfaces etc. You don't need to do so for class members and it's more idiomatic to let the constructor zero-initialise them automatically.

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

5 Comments

+1 for ` setting local variable dynamic arrays, strings, interfaces etc. to nil`
@David: Don't you mean "recommend setting return values" instead of "local variables" in the last paragraph?
Parameters too? Can you give an example where this is necessary? Off the top of my head I can't think of a reason for that, whether they are passed by value nor by ref.
@Ulrich you are right. I thought out parameters suffered too. In fact I wonder if they did in an older version of Delphi?
@David: Don't know. But the whole idea of out is to zero-initialize the respective parameter, so having to explicitly initialize it would make out pointless.
14

All the memory belonging to objects are initialized to 0 on object construction (heap allocation), so usually you don't need to initialize anything belonging to a class, default values (zero memory) are:

  • strings will be ''
  • integers will be 0
  • floating point variables will be 0
  • boolean will be false
  • pointers and object references will be nil
  • dynamic arrays will contain zero elements.

and so on.

For local variables and anything related to stack, it will contain garbage, so you're responsible to provide a meaningful value before using the variables.

Something like:

procedure Something;
var
  x: Integer;
begin
  ShowMessage(IntToStr(X));
end;

will show a random value.

4 Comments

what about SetLength in the constructor?
@pop32 SetLength to 0 is not neccesary, dynamic arrays will contain 0 elements.
@pop32: As I already wrote, dynamic arrays are always initialized to nil, i.e. zero length.
Small correction. There are a few types with special internal structure which must be initialised, otherwise they don't work at all. These will even be automatically initialized as local variables and when dynamically allocated using New. If they are dynamically alloacted using GetMem or ReallocMem, then you must also call Initialize to 'prepare the internal structure', and you must call Finalize before releasing the memory. Strings and Dynamic Arrays are two exmaples of such types. HOWEVER! I do recommend as a good habit, ALWAYS initialising your local variables - even strings!
8

Both SetLength calls are superfluous since dynamic arrays are initialized and finalized.

All fields in a class instance are initialized to their respective zero value, i.e. 0, nil, False, '' etc.

Local variables are initialized (and finalized) only if they are of a lifetime-Managed type like string, dynamic array or interface.

Comments

5

As the other answerers have said, you do not need to initialize class member fields.

You also asked about local variables. Yes, you do need to initialize those. All of them, except variables of one of the managed types:

  • AnsiString
  • UnicodeString
  • WideString
  • an interface type
  • dynamic array type
  • Variant

List taken from Barry Kelly's answer that Sertac pointed out in the comments: Which variables are initialized when in Delphi?

7 Comments

no, strings I think are initialized. What I meant was "only strings are initialized?"
@pop32 - No, strings are NOT initialized any more than any other local variables.
Local variables of managed types are initialized, see this answer.
@Sertac: Thanks, who am I to argue with Barry... :-) Edited.
@David: Huh? I am saying that you need to initialize local variables except ones of managed types... Or is this a case of comment and edit crossing paths on the way to the SO Server?
|
0

If you know in advance how large the array will be it could be a good practice to allocate it as a whole, it will avoids too many reallocations later, using memory better. Also clearing the array when you no longer use it will realease it memory (but Delphi knows how to clear them when they go out of scope).

Comments

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.