Hallo,
ja, in diesem kleinem Beispiel habe ich alles zur Laufzeit deklariert. Aber der Speicher wird erts durch den Aufruf von New belegt.
In der Paxis sieht das Arbeiten mit Listen inetwa so aus:
1. Man deklariert sich einen Listentyp. Dieser enthällt Neben den Daten noch einen Zeiger auf das nächste Element:
Quelltext
1: 2: 3: 4: 5: 6:
| Type pStrList = ^tStrList; tStrList = RECORD Data : STRING; Next : pStrList; end; |
2. Man deklariert sich eine (meist Objektglobale) Header Variable, um das erste Element der Liste wiederzufinden. Dies ist nur ein Zeiger, da kann noch kein String Reingeschrieben werden.
Quelltext
3. Um das ende (der noch leeren Liste) zu makieren setz man den Header im Constructor auf NIL;
Quelltext
4. Um Elemente einfach hizufügen zu können Scheibt man sich eine Methode die dies ermöglicht. Diese verwendet meist eine Lokale hilfs Variable. Der Wert ist aber auch nach dem verlassen der Funktion (und dem damit verbundenen freigeben der Hilfsvariablen) noch im Speicher. (Wegen der Einfachheit hier eine LIFO [Last In First Out] Liste)
Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9:
| procedure StrAdd(NeuerWert : String); VAR tmp : pStrList; begin New(tmp); // Hier wid erst die Variable erzeugt tmp^.Data := NeuerWert; // hier Wird Automatisch mehr Speicher für den vorher leeren String reserviert. tmp^.Next := Header; // Die bisherige Liste wird "hinter" das neue Element gehängt. Header := tmp; // Das neue Element der Liste Wird zum Header end; |
5. Wenn man nun ein einzelnes Element aus der Liste Raussuchen will muss man die Liste "Abklappern". Hier wird nach dem ersten Element mit den übergebenen Inhalt gesucht. Auch hierzu verwende ich wieder einen Hilfsvariable.
Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9:
| function FindFirstEle(Inhalt : STRING) : pStrList; VAR Runner : pStrList; // Dies ist wieder nur ein Zeiger (32 Bit egall was man über ihn ausliest) begin Runner := Header; // Den läufer an den Anfang der Liste setzen WHILE (Runner <> NIL) AND (Runner^.Data <> Inhalt) DO // Solang nicht am Ende der List und das Element nicht das gesuchte ist Runner := Runner^.Next; // Schiebe den Läufer ein Element weiter Result := Runner; // Ergebnis zurückgeben (kann ein Element mit dem String oder NIL sein) end; |
6. Wenn man irgentwann fertig ist, muss man den Speicher wieder Frei geben. Hier wird (weil es einfacher ist) die Komplette Liste freigegeben. Auch hierbei hilft wieder eine Variable, damit ich nicht die anderen Elemente der Liste verliere.
Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10:
| procedure ClearStrList; VAR tmp : pStrList; begin while (Header <> NIL) DO BEGIN // Solange Liste nicht Leer tmp := Header; // Das Aktuelle Element in die Hilfsvariable Herader := Header^.Next; // Den Listenanfang um eins nach hinten rücken Dispose(tmp); // Den Speicher auf den die Hilfsvariable Zeigt freigeben END; end; |
Das alles ist jetzt natürlich die Schnellversion, aber es soller einen Einduck der Technik geben. Der Speicher wird Dynamisch reserviert und bleibt reserviert, auch wenn die Hilfs-Variablen schon lange wieder freigegeben sind.
Man kann auch mit
Quelltext
speicher Reservieren, man kann dann nur nicht drauf zugreifen, weil man ihn im RAM nicht mehr wiederfindet. Deshalb sind die Hilfsvariablen notwendig Aber man benötigt nur eine davon Permanent (Header) um den Anfang der Liste immer wieder zu finden. Also auch wenn man 10.000 Elemente in der Liste hat muss man nur eine Hilfsvariable (welche 32 Bit belegt) permanent vorhalten.
Bliebe noch zu erwähnen, das sämlicher ode ungetestet weil hier im Forum getippt ist. Ählichen code habe ich aber schon häufiger verwendet

.
Luckie hat folgendes geschrieben: |
Unter zur Laufzeit erstellen verstehe ich, wenn ich in einem Edit den Variablennamen und den Typ angebe und dann wird die Variable angelegt. Und das geht defintiv nicht! |
Das geht natürlich nicht. Man müsste sich ja auch eine Variable mitführen alleine um sich den Variablennamen zu merken. Und wie würde der Code aussehen, wenn er das eine Mal mit der Der Variable HaenschenMueller und das andere mal mit LieschenMeier funktionieren müsste.
Deswegen sind Dynamische Variablen die, für die
zur Laufzeit der Befehl zum Speicher reservieren erteilt wird. (Alles was im Varblock steht zählt nicht obwohl diese Definition im Grunde auch auf den zutrifft)
Gruß
Klabautermann