Einzelnen Beitrag anzeigen

Jürgen Thomas

Registriert seit: 13. Jul 2006
Ort: Berlin
750 Beiträge
 
#5

Re: Array of Record & Speicher Freigaben

  Alt 13. Aug 2006, 20:24
Zitat von Real_Thunder:
Ich dachte mal gelesen zu haben, das der Inhalt eines Records nur Pointer sind, die auf den Eigenlichen Inhalt zeigen...
Ich habe den Eindruck, dass hier nicht klar getrennt wird.

Ein Record hat eine feste Größe; das Programm (bzw. das Betriebssystem) weiß also zu jedem beliebigen Zeitpunkt genau, wieviel Speicher aktuell - nämlich nach der aktuellen Länge des Arrays - für das gesamte Array benötigt wird.

Anhängen oder Einfügen eines neuen Elements bedeutet also für Programm/BS: einen ausreichend großen Speicherplatz bereitstellen (meistens klappt das nicht durch einfaches Vergrößern des bisherigen Platzes); den bisherigen Inhalt umkopieren, das neue Element einfügen.

Entfernen eines Elements bedeutet analog: das Element herausholen; die anderen Elemente verschieben; den überzähligen Platz freigeben. Der Speicherplatz für dieses Element wird automatisch freigegeben, weil das Array entsprechend weniger Platz belegt (dadurch bleiben meist viele kleine Speicherblöcke übrig, die nicht mehr sinnvoll belegt werden können).

Dieses "ständige" Verändern des Speicherplatzes beschäftigt Programm/BS erheblich mehr als sinnvoll und nötig. Dies gilt vor allem dann, wenn (z.B. beim Programmstart) viele Records eingefügt werden.

Zur Vereinfachung kann man bessere Möglichkeiten nutzen, nämlich TObjectList, TArrayList o.ä. Diese Listen enthalten tatsächlich nur Zeiger auf die Elemente und können von vornherein auf eine bestimmte Länge (d.h. Anzahl von Elementen) vorbereitet werden. Dann gilt aber das, was SirThornberry und Khabarakh gesagt haben: Jeder Record bekommt an der Stelle, an der er angelegt wird, seinen Speicher zugewiesen. Wenn er in der Liste eingetragen wird, wird dort nur der Pointer eingetragen. Wenn er aus der Liste gestrichen wird, wird dort nur der Pointer entfernt; der Record existiert nach wie vor. Also muss er irgendwo seine Gültigkeit und seinen Speicher verlieren.

Das hat zwei gefährliche Nebeneffekte: Wenn der Record aus der Liste entfernt, aber nicht ausdrücklich gelöscht wird, bleibt sein Speicher blockiert. Wenn er gelöscht wird, weil sein Gültigkeitsbereich abläuft, steht der Pointer nach wie vor in der Liste und zeigt ins Nirwana!

Auch deshalb ist zu empfehlen, anstelle von Records möglichst nur noch Objekte zu verwenden; diese müssen immer ausdrücklich angelegt und entfernt werden. (Unter NET erledigt Letzteres der Garbage Collector und nimmt dem Programmierer diese Arbeit ab.)

Apropos Arbeit:
Zitat von Real_Thunder:
Naja.. wenn Das Programm soweit ist, werde ich es mal strapazieren, und den Speicherbedaft beobachten..
Viel besser ist es, von Anfang an konsequent nachzudenken und zu programmieren. Alles, was nachträglich geändert werden muss, führt zu doppelter und dreifacher Arbeit.

Jürgen
#D mit C# für NET, dazu Firebird
früher: Delphi 5 Pro, Delphi 2005 Pro mit C# (also NET 1.1)
Bitte nicht sauer sein, wenn ich mich bei Delphi-Schreibweisen verhaue; ich bin inzwischen an C# gewöhnt.
  Mit Zitat antworten Zitat