Einzelnen Beitrag anzeigen

Benutzerbild von yankee
yankee

Registriert seit: 10. Mär 2004
1.134 Beiträge
 
Lazarus
 
#8

Re: Aufbau eines variablen Records

  Alt 18. Jan 2007, 22:09
Erstmal vorweg:
Ein string IST ein array. Ein array of char.

Wenn du dir den RAM vorstellst... Wie eine lange Tabelle:
Code:
Nummer: 1   2   3   4   5   6   7   8   9   ...
Inhalt: 0   0   0   5   H  A  L  L  O  ...
Jede Nummer kann 1 Byte speichern. Bei 32 Bit-Systemen sind die Nummern 32 Bit zahlen. Daher ist bei 32 Bit-Systemen auch bei 4GB RAM Schluss und du brauchst 64 Bit.

In meinem Beispiel hast du im RAM den string 'hallo' gespeichert. Dabei sind byte 1-4 zusammen ein Cardinal Wert, die die länge des Strings darstellen. Zumindest meine ich mich zu erinner, dass Delphi einen Cardinal verwendet... Ist fürs Verständnis aber egal:

Ein Buchstabe ist nur 1 Byte gross (zumindest im ASCII-Zeichensatz). Wenn du jetzt eine Variable
var s:string; hast, dann ist s eigentlich erstmal nur ein Pointer, also ein Cardinal mit dem Wert 1. Der zeigt einfach nur auf die Stelle im RAM, wo der String anfängt.
Da an der ersten Stelle des Strings die Länge des selbigen abgespeichert ist, weisst du genau, welche Felder der String belegt und kannst so mit dem String arbeiten.
Nachteil an dieser Konstruktion: Der String muss so, wie in meinem Beispiel hinternander weg im RAM sein. Wenn dein string dann 50 MB gross ist, dann brauchst du 50*10^20 Adressen, die hintereinander liegen. Wenn du dann bei so einem grossen array setlength() benutzt um den Array zu vergrössern, dann ist im RAM wahrscheinlich garnicht genug Platz hinter dem Array um einfach mal was anzuhängen, weil dort andere Daten liegen.
Du musst dir also einen neuen Array erstellen und alle bisherigen Daten in den neuen vergösserten Array kopieren. In C und Java ist der vorgang deutlicher, denn da gibt es kein setlength. Ein einmal initialisierter String ist eben einfach da und die einzige Möglichkeit ihn zu ändern ist eine geänderte Kopie zu erstellen.
Dieser Vorgang ist natürlich äusserst langsam.

Ein Lösungsansatz dafür sind verkettete Listen. Bei denen hast du am Ende jedes Elementes deines Arrays wieder einen Pointer auf das nächste Element. Daher müssen die Elemente im RAM nicht hintereinander sein. Die beschleunigt das löschen und anfügen von Elementen stark. Hat aber den Nachteil, dass du für den next-Pointer immer weitere 32 bit (bzw mehr, je nach CPU und OS) verschwendest. Ausserdem ist der Zugriff sehr langsam, wenn du jedes mal von Anfang 50000 mal dem Folgepointer folgen musst, bis du die richtige Datenposition hast.
Bei einem Array, der alle Elemente hinternander liegen hat, kannst du dir die Datenposition ganz einfach errechnen. Ausserdem kannst du auch mit einem Pointer über einen String iterieren.
Delphi-Quellcode:
var p: ^char;
    s:string;
begin
  s :='HALLO';
  p :=@s[1];
  showmessage(p^); //H
  inc(p);
  showmessage(p^); //A
  ...
end;
in diesem Beispiel setzen wir p als Pointer auf das erste Zeichen des strings. Also auf das 'H'. Dann erhöhen wir den Pointer (also die Adresse, auf die der Pointer zeigt) und schwupp finden wir an der stelle im RAM das A. So kann man immer wieder an die nächste stelle im RAM gehen, bis der string zu Ende ist (eigentlich noch weit darüber hinaus, bis es eine AV gibt, weil dein RAM zu Ende ist ^^).

Ein Array of Array ist demnach einfach, wie du bereits sagtest, ein ganz normaler eindemensionaler Array. Mit einem Pointer auf einen zweidemensionalen Array in jedem Element des ersten Arrays.


Ich hoffe das war verständlich .
Letzter Tipp: Drogen. Machen zwar nicht glücklich, geben einem aber wenigstens das Gefühl glücklich zu sein.

Have a lot of fun!
  Mit Zitat antworten Zitat