Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi Einfach Verkettete Liste (https://www.delphipraxis.net/93887-einfach-verkettete-liste.html)

Stillmatic 12. Jun 2007 19:14


Einfach Verkettete Liste
 
Hallo!

Wie kann ich den Speicherplatz einer einfach verketteten Liste frei geben??

PDaten = ^TDaten;
TDaten = record
info : TEinDatenSatz;
next : PDaten;
end;

TEinDatenSatz = record
ID : TID;
Title : TTitle;
end;

Liste : PDaten;

Wie gebe ich nun den Speicherplatz von Liste frei???

Apollonius 12. Jun 2007 19:19

Re: Einfach Verkettete Liste
 
Indem du alle Zeiger freigibst:
Delphi-Quellcode:
zeiger:=Liste;
while zeiger<>nil do
  begin
    znaechster:=zeiger.next;
    dispose(zeiger);
    zeiger:=znaechster;
  end;

Stillmatic 12. Jun 2007 22:03

Re: Einfach Verkettete Liste
 
Zitat:

Zitat von Apollonius
Indem du alle Zeiger freigibst:
Delphi-Quellcode:
zeiger:=Liste;
while zeiger<>nil do
  begin
    znaechster:=zeiger.next;
    dispose(zeiger);
    zeiger:=znaechster;
  end;


Ich bekomme bei Dispose Folgenden Fehler!!

First chance exception at $7C812A5B. Exception class EAccessViolation with message 'Access violation at address 00401B7B in module 'Aufgabe8.exe'. Write of address 425C3A46'. Process Aufgabe8.exe (2952)...

Weiß einer warum???

Nikolas 12. Jun 2007 22:39

Re: Einfach Verkettete Liste
 
Mal so geraten: Das Letzte Element hat keinen Nachfolger, den man lesen könnte.

Klaus01 13. Jun 2007 06:34

Re: Einfach Verkettete Liste
 
Guten Morgen,

zeigt der Poiter für den Nachfolger des letzen Elementes auf nil?
Wenn nicht, dann kracht es.
Grüße
Klaus

Stillmatic 13. Jun 2007 07:58

Re: Einfach Verkettete Liste
 
Bei mir sieht es im Moment so aus!

Delphi-Quellcode:
Marker   := Liste;

  while Marker <> nil do
    Begin
      Naechster:=Marker.next;
      dispose(Marker);
      Marker:=Naechster;
    end;
Aber bei dispose(Marker) kommt immer ein Fehler!
Wie kann ich denn den Nachfolger des letzten Elementes auf Nil setzen?

Naechster ist ja der Nachfolger von Marker!
...also
Ist Marker ---> Naechster.next oder was???

Klaus01 13. Jun 2007 08:06

Re: Einfach Verkettete Liste
 
Zitat:

Zitat von Stillmatic
Bei mir sieht es im Moment so aus!

Delphi-Quellcode:
Marker   := Liste;  // hier sollte der Anfang der Liste sein

  while Marker <> nil do
    Begin
      Naechster:=Marker.next; // der Nachfolger vom Marker wird ermittelt
      dispose(Marker);        // der Speicher für das Element Marker wird freigegeben
      Marker:=Naechster;      // der Zeiger vom Nachfolger wird dem Marker Element übergeben
    end;
Aber bei dispose(Marker) kommt immer ein Fehler!
Wie kann ich denn den Nachfolger des letzten Elementes auf Nil setzen?

Naechster ist ja der Nachfolger von Marker!
...also
Ist Marker ---> Naechster.next oder was???

Liste -> Marker,Nachfolger -> erstes Element,Nachfolger -> zweites Element,Nachfolger -> drittes Element,Nachfolger -> nil

Normalerweise wird bei der Erstellung einer Liste immer der Nachfolger zuerst auf nil gesetzt,
gibt es dann ein weiteres Element wird der Nachfolger auf diese Element gesetzt.

Hier ist es ganz gut erklärt -> http://de.wikipedia.org/wiki/Liste_(Datenstruktur)

Grüße
Klaus

hsg 13. Jun 2007 08:57

Re: Einfach Verkettete Liste
 
Zeig doch mal den Code, wie du deine Liste überhaupt erstellst. Ich befürchte eher, dass dort bereits dein Problem liegt .

alzaimar 13. Jun 2007 09:32

Re: Einfach Verkettete Liste
 
Eine einfache verkettete Liste sollte immer ein 'Dummy-Element' (HEAD) beinhalten, das auf das erste Element der Liste zeigt. Elemente werden immer zwischen HEAD und HEAD.next eingefügt. Da HEAD.next anfangs mit nil belegt ist, kann man nichts falsch machen:

Delphi-Quellcode:
Type
  PLinkedList =^TLinkedList;
  TLinkedList = Record
    llNext : PLinkedList;
    llData : TInfo
  End;

Var
  Head : PLinkedList;

Procedure InitList;
Begin
  New (Head);
  Head^.llNext := Nil;
End;

Procedure AddToList (aNodeInfo : TInfo);
Var
  p : PLinkedList;

Begin
  New (P);
  p^.llData := aNodeInfo;
  p^.llNext := HEAD^.llNext;
  Head^.llNext := p
End;
Dann funktioniert der Löschcode auch.

Stillmatic 13. Jun 2007 11:50

Re: Einfach Verkettete Liste
 
Das klappt bei mir alles nicht so wie ich will!
Ich bekomme immer wieder Fehler " Access Violation at Adress"!!

Also ich habe meine Typdeklaration so!
Delphi-Quellcode:
type
  PDaten     = ^TDaten;
  TDaten     = record
                  info : TEinDatensatz;      // Daten
                  next : PDaten;            // nächster
                end;
TEinDatensatz ist so deklariert

Delphi-Quellcode:
TEinDatensatz = record
               ID     : TID;      
               Title  : TTitle;    
             end;
Nun hab ich mir eine Variable angelegt
Delphi-Quellcode:
Liste: PDaten;
Nun muss ich 2 Proceduren schreiben!
Die eine gibt den kompletten speicher wieder frei(Procedure)....
und die andere schreibt ein Element vom typ TEinDatensatz in die Liste(Procedure--> auf Knopfdruck)!
Das heißt das wenn auf einen Button gedrückt wird öffnet sich ein OpenDialog wo man eine Datei auswählen kann welche dann in die Liste geschrieben wird.Wenn man eine Datei angefügt hat und eine nächste reinschreiben möchte darf das alte natürlich nicht überschrieben werden??

:gruebel:

Nur ich weiß nicht wie man das ganze jetzt umsetzt ohne diese lästigen Fehler immer zu bekommen??
:?:

alzaimar 13. Jun 2007 11:55

Re: Einfach Verkettete Liste
 
Nimm doch einfach meine Prozeduren...

Stillmatic 13. Jun 2007 11:58

Re: Einfach Verkettete Liste
 
Da bekomme ich aber die selben Fehler!

Stillmatic 13. Jun 2007 12:50

Re: Einfach Verkettete Liste
 
Bei diesem Verfahren wird das neue Element an erster Stelle geschrieben und alle anderen einen nach unten gesetzt!
Delphi-Quellcode:
Procedure AddToList (aNodeInfo : TInfo);
Var
  p : PLinkedList;

Begin
  New (P);
  p^.llData := aNodeInfo;
  p^.llNext := HEAD^.llNext;
  Head^.llNext := p
End;
Wie kann man das ganze jetzt so umdrehen das, das neue Element an das Ende geschrieben wird?

hoika 13. Jun 2007 13:15

Re: Einfach Verkettete Liste
 
Hallo,

schreib dir eine Methode,
die den letzten Eintrag sucht
(das ist der mit Next=NIL),
erzeuge einen neuen Koten, setze dort Next auf NIL
und setzen Next des (gerade gefundenen) Knoten auf
deinen neu erzeugten.


Heiko

Stillmatic 18. Jun 2007 18:28

Re: Einfach Verkettete Liste
 
Was ist eigentlich der Unterschied zwischen

p^.llData := aNodeInfo;
p^.llNext := HEAD^.llNext;
Head^.llNext := p

und

p.llData := aNodeInfo;
p.llNext := HEAD.llNext;
Head.llNext := p

Also meine Frage ist wofür ist dieses "^" Zeichen nötig???

DeddyH 18. Jun 2007 18:39

Re: Einfach Verkettete Liste
 
Das ^-Zeichen hinter einer Zeigervariablen steht für Dereferenzierung, d.h. es ist nicht der Zeiger an sich gemeint, sondern die dahinter liegenden Daten.

Stillmatic 18. Jun 2007 18:42

Re: Einfach Verkettete Liste
 
Aber unbedingt hischreiben muss man es nicht??

Ist also eher ein Zeichen zur verdeutlichung, oder???

DeddyH 18. Jun 2007 18:44

Re: Einfach Verkettete Liste
 
Zitat:

Delphi-Quellcode:
p^.llData := aNodeInfo;
p^.llNext := HEAD^.llNext;
Head^.llNext := p

Besitzt ein Zeiger die Felder llData und llNext? :mrgreen: :stupid:

alzaimar 19. Jun 2007 08:05

Re: Einfach Verkettete Liste
 
Hi.

Das ^ Zeichen dereferenziert einen Zeiger: Wenn P ein Zeiger auf einen Record 'TMyRecord' ist (also P ist nur eine Adresse), dann bezeichnet 'P^' das, worauf P zeigt, in diesem Fall den Record 'TMyRecord'.

Also würde eigentlich 'P.bla' keinen Sinn ergeben. Nun ist der Delphi-Compiler ja nett zu uns und verzeiht einige Tippfehler, weswegen er das '^' nach dem P dazudichtet.

Stillmatic 21. Jun 2007 17:43

Re: Einfach Verkettete Liste
 
Ich habe schon wieder ein derbes Problem!!

Ich möchte eine Liste füllen!
Als erstes wird die Funktion ListFüllen aufgerufen, in der dann ein neues Element gefüllt wird durch den Aufruf der Function NewOneListElement.
In der While Schleife suche ich die Dateinamen die in First(noch eine Liste) gespeichert sind heraus und schneide die Dateierweiterung(.txt) ab. Die einzelnen Dateinamen ohne Extension werden dann in einem String gespeichert, den ich nachher als Titel benutze.

Mein Problem liegt aber darin das an der Stelle {Ausgabe.Id := PPointers;} in der Function NewOneListElement einfach in der List ein Wert verändert wird obwohl ich an der Stelle garnix mit der List mache!

Ich kann mir das nicht erklären!!!!

Delphi-Quellcode:
function ListFüllen :POnelist;
var temp : PDatensatz;
    Name : String;
 Ausgabe : POnelist;
Begin
  Name := '';
  temp := first;
  //Neues Element anlegen und Füllen
  Ausgabe := NewOneListElement;
    while temp <> Nil do
     Begin
       Name := Name + ExtractFileName(temp.info.Titel);
       Name := StringReplace(Name, '.txt','',[]);
       temp := temp.next;
     end;
    Ausgabe.Titel := Name;
    //Ausgabe an das ende der Liste anfügen
    Ausgabe.next := List;
    List := Ausgabe;
    ListFüllen := List;
end;

Delphi-Quellcode:
function NewOneListElement; :POnelist;
var Ausgabe : POnelist;
Begin
  new(Ausgabe);
  Ausgabe^.next := Nil;
  Ausgabe^.daten := first;
  inc(PPointers);
  Ausgabe.Id   := PPointers; //genau an dieser Stelle tritt der Fehler auf!!//
  NewPlayElement := Ausgabe;
end;

Stillmatic 21. Jun 2007 20:54

Re: Einfach Verkettete Liste
 
Weiß auch keiner, wo da das Problem liegen könnte????

mkinzler 21. Jun 2007 21:04

Re: Einfach Verkettete Liste
 
Vielleicht solltest du den direkten Zugriff auf globale Variablen durch Parameter ersetzen.


Alle Zeitangaben in WEZ +1. Es ist jetzt 20:06 Uhr.

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz