Autor Beitrag
Stoffel1984
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 219

Win NT, Win 2000
D6 Prof
BeitragVerfasst: Fr 13.02.04 09:43 
Hallo,

bei nem Eindimensionalen Array vergrößere ich das dynamische Array ja so:

ausblenden Delphi-Quelltext
1:
Setlength(Array,Length(Array)+1);					


Wie aber vergrößere ich

1. Die Erste Dimension

2. Die Zweite Dimension

des Arrays?!

Hab mir schon das Array Tutorial durchgelesen - allerdings hab ich das nicht drin gefunden!

Danke schonmal,

Stoffel
Christian S.
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 20451
Erhaltene Danke: 2264

Win 10
C# (VS 2019)
BeitragVerfasst: Fr 13.02.04 09:55 
Hallo!

Doch, es steht im Array-Tutorial. Dort werden zweidimensionale Arrays mit einer Größe versehen. Und genauso macht man es auch, wenn man man einem Array eine neue Größe verpasst.

Stichwort: "Ein zweidimensionales Array ist ein 1-dim Array, dessen Elemente wieder Arrays sind."

MfG
Peter

_________________
Zwei Worte werden Dir im Leben viele Türen öffnen - "ziehen" und "drücken".
Stoffel1984 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 219

Win NT, Win 2000
D6 Prof
BeitragVerfasst: Fr 13.02.04 10:10 
Hallo,

danke erstmal für die schnelle Antwort!
Deinem Beispiel zur Folge müsste es am Beispiel einer Tabelle
also so sein:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
SetLength(my_2d_int_array,3); 
// Das Array mit erstmal 3 Dimensionen erstellen (Zeilen)
SetLength(my_2d_int_array[0],1); 
// Erste Dimension (Zeile) bekommt die Länge 1 zugewiesen
SetLength(my_2d_int_array[1],5); 
// Zweite Dimension (Zeile) bekommt die Länge 5 zugewiesen
SetLength(my_2d_int_array,[2],7);
// Dritte Dimension (Zeile) bekommt die Länge 7 zugewiesen


Theoretisch kann ich das Array in der zweiten Zeile dann folgendermaßen vergrößern:

ausblenden Delphi-Quelltext
1:
SetLength(my_2d_int_array[1],Length(my_2d_int_array)+1);					


Hab ich das so richtig interpretiert?


Gruß, Stoffel
AndyB
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 1173
Erhaltene Danke: 14


RAD Studio XE2
BeitragVerfasst: Fr 13.02.04 10:46 
Zitat:
jeweils um 1 verlängern

Das würde ich unterlassen, denn der Speichermanager dankt es dir mit einem enormen Speicherverbrauch. Aus diese weise werden aus 10KB ein Verbrauch von ca. 200MB.
Besser du ermittelst zuerst die maximale Länge des Arrays und setzt diese, anstatt jedesmal um 1 Element zu vergrößern. Und wenn das nicht möglich ist, solltest du das Array immer um einen Delta-Wert erhöhen und eine Variable "Effektive Länge" mitführen, die die Anzahl der genutzen Elemente enthält. Am Schluss setzt du dann die Arraylänge auf diese "Effektive Länge". Damit hast du nur 2 mal Speicher reserviert und nicht wie bei der +1 Methode n mal.

_________________
Ist Zeit wirklich Geld?
Stoffel1984 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 219

Win NT, Win 2000
D6 Prof
BeitragVerfasst: Fr 13.02.04 10:57 
Hallo,

das mit dem +1 war als Beispiel weil es in meiner Schleife nunmal so geschehen muss. Aber effektiv lese ich zuerst Length des Arrays aus und vergrößere wenn es sein muss um 1.

So meintest du es doch!?
Oder hab ich dich grade missverstanden?

Stoffel
Christian S.
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 20451
Erhaltene Danke: 2264

Win 10
C# (VS 2019)
BeitragVerfasst: Fr 13.02.04 16:01 
Hallo!

Was AndyB völlig zu Recht meinte, ist, dass Delphi bei der Längenänderung eines Arrays das Array immer komplett kopiert. Dies dauert erstens sehr lange und verbraucht mit der Zeit auch eine Menge Speicher. Daher sollte man SetLength so wenig wie möglich nutzen.

Dein Code, um die zweite Zeile zu verlängern, ist nicht ganz korrekt. Denn Du rufst die Länge des "Haupt"arrays ab und verwendest diese für ein "Unter"array. Du solltest als Length(my_2d_int_array[1]) verwenden.

MfG
Peter

_________________
Zwei Worte werden Dir im Leben viele Türen öffnen - "ziehen" und "drücken".
Brainiac
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Fr 13.02.04 16:43 
Peter Lustig hat folgendes geschrieben:
Was AndyB völlig zu Recht meinte, ist, dass Delphi bei der Längenänderung eines Arrays das Array immer komplett kopiert.


Echt? Ich dachte, dass macht es nur, wenn die Lücke im Speicher bis zum nächsten belegten Block zu klein wird. Außerdem, dachte ich, wird diese Lücke dann doch für die nächste passende GetMem-änliche Belegung genutzt.
Stoffel1984 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 219

Win NT, Win 2000
D6 Prof
BeitragVerfasst: Fr 13.02.04 21:39 
Peter Lustig hat folgendes geschrieben:
Was AndyB völlig zu Recht meinte, ist, dass Delphi bei der Längenänderung eines Arrays das Array immer komplett kopiert. Dies dauert erstens sehr lange und verbraucht mit der Zeit auch eine Menge Speicher. Daher sollte man SetLength so wenig wie möglich nutzen.


Danke... :oops:

Wie ist es dann möglich effektiv mit dyn. Arrays in Schleifen zu arbeiten?

Sollte doch möglich sein, oder?

Stoffel
AndyB
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 1173
Erhaltene Danke: 14


RAD Studio XE2
BeitragVerfasst: Fr 13.02.04 21:45 
Stoffel1984 hat folgendes geschrieben:
Wie ist es dann möglich effektiv mit dyn. Arrays in Schleifen zu arbeiten?

Liest du eigentlich bei meinem Posting n nur den ersten Satz?


Zitat:
Echt? Ich dachte, dass macht es nur, wenn die Lücke im Speicher bis zum nächsten belegten Block zu klein wird.

Da der Delphi-Speichermanager auf 4 Byte ansrichtet, ist das bei vergrößern von Arrays fast überhaupt nicht möglich.

Zitat:
Außerdem, dachte ich, wird diese Lücke dann doch für die nächste passende GetMem-änliche Belegung genutzt.

Das schon, aber wenn nichts kleineres kommt, bleibt der Speicher "von Windows aus gesehen" reserviert. Und es ist in einer Schleife zum vergrößern des Arrays recht selten, dass in den alten Platz etwas hineinpasst. Zudem muss eine gesamte Speicherseite frei sein, damit der Delphi-Speichermanager wieder Speicher an Windows zurückgibt.

_________________
Ist Zeit wirklich Geld?