![]() |
Die verkettete Liste
Delphi-Quellcode:
Ich bastele soeben an einer verketteten Liste (TParameterList). Die Routinen zum Hinzufügen und Abfragen eines Parameters über den Index stehen schon. Jedoch funktioniert dieses Abfragen nicht richtig.
type
PItem = ^TItem; TItem = record Data: TParameter; Next: PItem; end; TParameterlist = class private FFirst: PItem; FCurrently: PItem; procedure TParameterlist.AddAtEnd(AParameter: TParameter); var NewItem: PItem; begin New(NewItem); NewItem.Data := AParameter; NewItem.Next := nil; //If list is still empty if (FFirst = nil) then begin FFirst := NewItem; FCurrently := NewItem; end //list just has content else begin FCurrently := FFirst; //go step by step to the end while (FCurrently.Next <> nil) do FCurrently := FCurrently.Next; FCurrently.Next := NewItem; end; inc(FCount); end; function TParameterlist.GetParameter(index: integer): TParameter; var i: integer; begin //List index mustn't be higher than the maximum! if (index <= High) then begin //return the first parameter if (index = 0) then result := FFirst.Data else begin i := 0; //go step by step through the list and fetch the right one! FCurrently := FFirst; while (i < index) do begin inc(i); FCurrently := FCurrently.Next; end; result := FCurrently.Data; end; end else result := nil; end; //Ausgabe im Programm procedure TForm1.Button1Click(Sender: TObject); begin list := TParameterlist.Create; param := TParameter.Create('uschi','string'); end; procedure TForm1.Button2Click(Sender: TObject); var i: integer; begin for i := 0 to 6 do begin param.Name := 'Nummer '+inttostr(i); list.AddAtEnd(param); end; end; procedure TForm1.Button3Click(Sender: TObject); var i: integer; begin //egal, welchen Index ich nehme, er gibt immer 'Nummer 6' aus =( showmessage(list.Parameter[2].Name); end; procedure TForm1.Button4Click(Sender: TObject); begin showmessage(inttostr(list.count)); end; Egal, welchen Index ich bei List.Parameters[index].Name angebe, ich bekomme immer den Namen des letzten Eintrage (hier "Nummer 6")). Sieht jemand Fehler im Code? :lupe: :gruebel: Hinweis: Es gibt einen Crosspost in der EE! ;) |
Re: Die verkettete Liste
Hrrrm param ist eine Klasse? Sollte da nicht für jeden Listeneintrag eine eigene Instanz erstellt werden? Sonst zeigen die Pointer von jedem Eintrag ja alle auf ein und das selbe Objekt.
Du änderst immer wieder param.name vom selben Objekt und hängst dann die Referenz von Param in die Liste. |
Re: Die verkettete Liste
Ja fällt mir jetzt auch auf. Ich sollte vielleicht die Instanzen innerhalb von TParameterlist erstellen. ?!?
|
Re: Die verkettete Liste
Delphi-Quellcode:
Habe die Methode jetzt so abgeändert.
procedure TParameterlist.AddAtEnd(Name, DataType: string);
var param: TParameter; NewItem: PItem; begin param := TParameter.Create(Name,DataType); //If list is still empty if (FFirst = nil) then begin FFirst.Data := param; FCurrently := FFirst; end //list just has content else begin SetPointerAtPosition(High); New(NewItem); NewItem.Data := param; NewItem.Next := nil; FCurrently.Next := NewItem; end; inc(FCount); end; Es wird nicht mehr TParameter übergeben, sondern Name und DataType. Es wird, denke ich ;) , jetzt immer wieder eine neue Instanz erstellt. Jedoch crash es gleich bei FFirst.Data := param mit einer AV. Was tun? |
Re: Die verkettete Liste
Delphi-Quellcode:
vielleicht so, denn in eine leere Liste (nil) kann man nichts schreiben.
//If list is still empty
if (FFirst = nil) then begin New(NewItem) NewItem.Data := param; NewItem.Next:=nil; FFirst:=NewItem; FCurrently := FFirst; end Grüße Klaus |
Re: Die verkettete Liste
Krass es läuft! :bouncing4: :bounce1: :dancer: :dancer2: :witch: :coder: :cheers: :love:
|
Re: Die verkettete Liste
Jetzt habe ich das nächste Problem:
Nun ist die Methode Clear dran. Erstmal die ganze Unit nochmal:
Delphi-Quellcode:
Habe mir dazu eine Testanwendung gebastelt mit 5 Buttons. Wenn ich 6 Items adde, dann alle mit Clear entferne und dann wieder adden will, dann kommt in SetPointerAtPosition an der markierten Stelle eine AV. Wieso? :wiejetzt: :wiejetzt:
unit ParameterList;
interface uses Parameter; type PItem = ^TItem; TItem = record Data: TParameter; Next: PItem; end; TParameterlist = class private FFirst: PItem; FCurrently: PItem; FCount: integer; function GetParameter(index: integer): TParameter; procedure SetParameter(index: integer; const Value: TParameter); procedure SetPointerAtPosition(index: integer); public property Parameter[index: integer]: TParameter read GetParameter write SetParameter; property Count: integer read FCount; procedure AddAtFirst(Name, DataType: string); procedure AddAtPos(Name, DataType: string); procedure AddAtEnd(Name, DataType: string); procedure Delete(index: integer); procedure Swap(index1, index2: integer); procedure Clear; function High: integer; constructor Create; destructor Destroy; end; implementation { TParameterlist } procedure TParameterlist.SetPointerAtPosition(index: integer); var i: integer; begin if (index <= High) then begin FCurrently := FFirst; i := 0; while (i < index) do begin FCurrently := FCurrently.Next; //<-- AV inc(i); end; end; end; procedure TParameterlist.AddAtEnd(Name, DataType: string); var param: TParameter; NewItem: PItem; begin param := TParameter.Create(Name,DataType); //If list is still empty if (FFirst = nil) then begin New(NewItem); NewItem.Data := param; FFirst := NewItem; FCurrently := FFirst; end //list just has content else begin SetPointerAtPosition(High); New(NewItem); NewItem.Data := param; NewItem.Next := nil; FCurrently.Next := NewItem; end; inc(FCount); end; procedure TParameterlist.Clear; var ptemp1,ptemp2: PItem; begin if (FCount > 0) then begin ptemp1 := FFirst; while (ptemp1 <> nil) do begin ptemp2 := ptemp1.Next; Dispose(ptemp1); ptemp1 := ptemp2; end; FCount := 0; end; end; constructor TParameterlist.Create; begin FFirst := nil; FCurrently := nil; FCount := 0; end; procedure TParameterlist.Delete(index: integer); begin end; destructor TParameterlist.Destroy; begin inherited; end; function TParameterlist.GetParameter(index: integer): TParameter; var i: integer; begin //List index mustn't be higher than the maximum! if (index <= High) then begin //return the first parameter if (index = 0) then result := FFirst.Data else begin i := 0; //go step by step through the list and fetch the right one! FCurrently := FFirst; while (i < index) do begin inc(i); FCurrently := FCurrently.Next; end; result := FCurrently.Data; end; end else result := nil; end; function TParameterlist.High: integer; begin result := FCount - 1; end; procedure TParameterlist.SetParameter(index: integer; const Value: TParameter); begin end; procedure TParameterlist.Swap(index1, index2: integer); begin end; procedure TParameterlist.AddAtFirst(Name, DataType: string); begin end; procedure TParameterlist.AddAtPos(Name, DataType: string); begin end; end. |
Re: Die verkettete Liste
Delphi-Quellcode:
irgendwo laufen Deine Index und die Anzahl der Elemente auseinander.
while (i < index) and (FCurrently <> nil) do
begin if FCurrently <> nil then FCurrently := FCurrently.Next; //<-- keine AV inc(i); end; Grüße Klaus |
Re: Die verkettete Liste
Zitat:
|
Re: Die verkettete Liste
Du sollst eine Prüfung auf nil einbauen. Und vergiss auch nicht die TParameter-Objekte in data jeweils freizugeben.
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 06:26 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