4 Stimmen

Muss ich setLength ein dynamisches Array bei der Initialisierung?

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;

Und welche Typen werden bei der Erstellung initialisiert? Zum Beispiel das, was ich in der Klasse deklariert habe. Ist FBool garantiert falsch? Ist FInt garantiert gleich 0? Ist Fstr garantiert gleich ''?

Wie sieht es mit der lokalen Ebene aus? Nur Streicher?

Ich verwende Delphi XE.

14voto

jachguate Punkte 16748

Der gesamte zu den Objekten gehörende Speicher wird bei der Objekterstellung (Heap-Allokation) auf 0 initialisiert, so dass Sie normalerweise nichts, was zu einer Klasse gehört, initialisieren müssen, sondern nur die Standardwerte (Null-Speicher):

  • Zeichenketten werden ''
  • Ganzzahlen werden 0 sein
  • Fließkomma-Variablen werden zu 0
  • boolescher Wert ist false
  • Zeiger und Objektreferenzen sind gleich Null
  • dynamische Arrays enthalten keine Elemente.

und so weiter.

Lokale Variablen und alles, was mit dem Stack zusammenhängt, enthält Müll, so dass Sie dafür verantwortlich sind, einen sinnvollen Wert anzugeben, bevor Sie die Variablen verwenden.

Etwa so:

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

zeigt einen Zufallswert an.

14voto

David Heffernan Punkte 585606

Dynamische Arrays sind verwaltete Typen und werden daher immer mit nil , gleichbedeutend mit SetLength(..., 0) . Sie müssen dies nie tun.

Der einzige Fall, in dem Sie erwischt werden können, ist, wenn Sie ein dynamisches Array aus einer Prozedur als Funktionsrückgabewert zurückgeben. Ein Funktionsrückgabewert ist in Wirklichkeit nur ein impliziter var-Parameter.

Betrachten Sie den folgenden 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;

Ausgabe

X
XX
XXX
XXXX
XXXXX
X
X

Was hier vor sich geht, ist, dass der Compiler als Optimierung die implizite lokale Variable innerhalb der Schleife nicht neu initialisieren will.

Daher empfehle ich, Rückgabewerte, die dynamische Arrays, Strings, Schnittstellen usw. sind, auf Null zu setzen. Bei Klassenmitgliedern ist das nicht nötig. Es ist idiomatischer, sie vom Konstruktor automatisch null-initialisieren zu lassen.

7voto

Uli Gerhardt Punkte 13513

Beide SetLength-Aufrufe sind überflüssig, da dynamische Arrays initialisiert und finalisiert werden.

Alle Felder in einer Klasseninstanz werden auf ihren jeweiligen Nullwert initialisiert, d. h. 0, nil, False, '' usw.

Lokale Variablen werden nur dann initialisiert (und finalisiert), wenn sie von einem lebenszeitverwalteten Typ wie String, dynamisches Array oder Schnittstelle sind.

4voto

Marjan Venema Punkte 18796

Wie die anderen Antwortenden bereits gesagt haben, müssen Sie keine Klassenmitgliederfelder initialisieren.

Sie haben auch nach lokalen Variablen gefragt. Ja, die müssen Sie initialisieren. Alle, außer Variablen eines der verwalteten Typen:

  • AnsiString
  • UnicodeString
  • WideString
  • einen Schnittstellentyp
  • dynamischer Array-Typ
  • Variante

Die Liste stammt aus der Antwort von Barry Kelly, auf die Sertac in den Kommentaren hingewiesen hat: Welche Variablen werden in Delphi initialisiert?

0voto

Wenn Sie im Voraus wissen, wie groß das Array sein wird, könnte es eine gute Praxis sein, es als Ganzes zuzuweisen, es vermeidet zu viele Neuzuweisungen später und nutzt den Speicher besser. Auch das Löschen des Arrays, wenn Sie es nicht mehr benutzen, gibt den Speicher wieder frei (aber Delphi weiß, wie man sie löscht, wenn sie aus dem Bereich herausgehen).

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X