[Delphi] Problem mit doppelt verketteter liste...

Dieses Thema im Forum "Programmierung & Entwicklung" wurde erstellt von coach, 31. Oktober 2006 .

Schlagworte:
  1. 31. Oktober 2006
    Problem mit doppelt verketteter liste...

    joar, habe folgende units gemacht:

    Mein Listenelement:
    Code:
    unit uKListenelement;
    
    {$mode objfpc}{$H+}
    
    interface
    
    uses
     Classes, SysUtils; 
     
    type KListenelement=class
     protected
     inhalt:TObject;
     previous:KListenelement;
     next:KListenelement;
     public
     constructor create;
     procedure set_previous(p:KListenelement);
     procedure set_next(n:KListenelement);
     procedure set_inhalt(wert:TObject);
     function get_inhalt:TObject;
     function get_previous:KListenelement;
     function get_next:KListenelement;
     end;
    
    implementation
    
    constructor KListenelement.create;
    begin
     previous:=nil;
     next:=nil;
     inhalt:=nil;
    end;
    
    procedure KListenelement.set_previous(p:KListenelement);
    begin
     previous:=p;
    end;
    
    procedure KListenelement.set_next(n:KListenelement);
    begin
     next:=n;
    end;
    
    procedure KListenelement.set_inhalt(wert:TObject);
    begin
     inhalt:=wert;
    end;
    
    function KListenelement.get_inhalt:TObject;
    begin
     result:=inhalt;
    end;
    
    function KListenelement.get_previous:KListenelement;
    begin
     result:=previous;
    end;
    
    function KListenelement.get_next:KListenelement;
    begin
     result:=next;
    end;
    
    end.
    
    Meine Liste:
    Code:
    unit uKListe;
    
    {$mode objfpc}{$H+}
    
    interface
    
    uses
     Classes, SysUtils, uKListenelement;
     
    type KListe=class
     private
     anfang:KListenelement;
     aktuell:KListenelement;
     ende:KListenelement;
     hinter_dem_ende:boolean;
     public
     constructor create;
     procedure next;
     procedure previous;
     procedure to_first;
     procedure to_last;
     procedure insert_before(insert:TObject);
     procedure insert_behind(insert:TObject);
     procedure update(inhalt:TObject);
     procedure delete;
     function get_inhalt:TObject;
     function is_empty:boolean;
     function is_before:boolean;
     function is_behind:boolean;
     end;
    
    implementation
    
    constructor KListe.create;
    begin
     anfang:=nil;
     aktuell:=nil;
     ende:=nil;
     hinter_dem_ende:=false;
    end;
    
    procedure KListe.next;
    begin
     if aktuell<>nil then
     begin
     aktuell:=aktuell.get_next;
     hinter_dem_ende:=(aktuell=nil);
     end
     else
     begin
     hinter_dem_ende:=true;
     end;
    end;
    
    procedure KListe.previous;
    begin
     if aktuell<>nil then
     begin
     aktuell:=aktuell.get_previous;
     hinter_dem_ende:=false;
     end
     else
     hinter_dem_ende:=true;
    end;
    
    procedure KListe.to_first;
    begin
     if is_empty then
     hinter_dem_ende:=false
     else
     aktuell:=anfang;
    end;
    
    procedure KListe.to_last;
    begin
     if is_empty then
     hinter_dem_ende:=true
     else
     aktuell:=ende;
    end;
    
    procedure KListe.insert_before(insert:TObject);
    var listenelement:KListenelement;
    begin
     if not(is_before) then
     begin
     listenelement:=Klistenelement.create;
     listenelement.set_inhalt(insert);
     listenelement.set_next(aktuell);
     if aktuell<>nil then
     begin
     listenelement.set_previous(aktuell.get_previous);
     if aktuell.get_previous<>nil then
     aktuell.get_previous.set_next(listenelement)
     else anfang:=listenelement;
     aktuell.set_previous(listenelement);
     end
     else
     begin
     listenelement.set_previous(ende);
     if ende<>nil then
     ende.set_next(listenelement);
     ende:=listenelement;
     if anfang=nil then
     anfang:=listenelement;
     end;
     end;
    end;
    
    procedure KListe.insert_behind(insert:TObject);
    var listenelement:KListenelement;
    begin
     if is_empty then
     begin
     listenelement:=KListenelement.create;
     listenelement.set_inhalt(insert);
     anfang:=listenelement;
     ende:=listenelement;
     end;
     if (aktuell=nil) and (hinter_dem_ende=false) then
     begin
     listenelement:=KListenelement.create;
     listenelement.set_inhalt(insert);
     listenelement.set_next(anfang);
     listenelement.set_previous(nil);
     anfang.set_previous(listenelement);
     anfang:=listenelement;
     end;
     if aktuell=ende then
     begin
     listenelement:=KListenelement.create;
     listenelement.set_inhalt(insert);
     listenelement.set_next(nil);
     listenelement.set_previous(aktuell);
     aktuell.set_next(listenelement);
     ende:=listenelement;
     end
     else
     begin
     listenelement:=KListenelement.create;
     listenelement.set_inhalt(insert);
     listenelement.set_next(listenelement.get_next);
     listenelement.set_previous(aktuell);
     aktuell.set_next(listenelement);
     aktuell.get_next.set_previous(listenelement);
     end;
    end;
    
    procedure KListe.update(inhalt:TObject);
    begin
     if aktuell<>nil then
     aktuell.set_inhalt(inhalt);
    end;
    
    procedure KListe.delete;
    var item:KListenelement;
    begin
     if aktuell<>nil then
     begin
     if anfang=ende then
     begin
     anfang:=nil;
     aktuell.destroy;
     aktuell:=nil;
     ende:=nil;
     end
     else
     if (aktuell.get_previous<>nil) and (aktuell.get_next<>nil) then
     begin
     aktuell.get_previous.set_next(aktuell.get_next);
     aktuell.get_next.set_previous(aktuell.get_previous);
     item:=aktuell.get_next;
     aktuell.destroy;
     aktuell:=item;
     end
     else
     if aktuell=anfang then
     begin
     aktuell.get_next.set_previous(nil);
     item:=aktuell.get_next;
     aktuell.destroy;
     aktuell:=item;
     anfang:=item;
     end
     else
     if aktuell=ende then
     begin
     aktuell.get_previous.set_next(nil);
     item:=aktuell.get_previous;
     aktuell.destroy;
     ende:=item;
     aktuell:=nil;
     end;
     end;
    end;
    
    function KListe.get_inhalt:TObject;
    begin
     if aktuell<>nil then
     result:=aktuell.get_inhalt
     else
     result:=nil;
    end;
     
    function KListe.is_empty:boolean;
    begin
     result:=(anfang=nil);
    end;
    
    function KListe.is_before:boolean;
    begin
     result:=(aktuell=nil) and (not(hinter_dem_ende));
    end;
    
    function KListe.is_behind:boolean;
    begin
     result:=(aktuell=nil) and (hinter_dem_ende);
    end;
    
    end.
    
    Mein Testprogg:
    Code:
    unit uMain;
    
    {$mode objfpc}{$H+}
    
    interface
    
    uses
     Classes, SysUtils, LResources, Forms, Controls, Graphics, Dialogs, uKListe,
     ExtCtrls, Buttons;
    
    type
    
     KListitem=class(TObject)
     protected
     name:string;
     zuege:string;
     public
     procedure set_name(n:string);
     procedure set_zuege(z:string);
     function get_name:string;
     function get_zuege:string;
     end;
     
     Tform_main = class(TForm)
     button_zurueck: TButton;
     button_einfuegen: TButton;
     button_vor: TButton;
     labelededit_name: TLabeledEdit;
     labelededit_zuege: TLabeledEdit;
     procedure FormCreate(Sender: TObject);
     procedure button_einfuegenClick(Sender: TObject);
     procedure button_vorClick(Sender: TObject);
     procedure button_zurueckClick(Sender: TObject);
     end;
    
    var
     form_main: Tform_main;
     liste:KListe;
    
    implementation
    
    procedure KListitem.set_name(n:string);
    begin
     name:=n;
    end;
    
    procedure KListitem.set_zuege(z:string);
    begin
     zuege:=z;
    end;
    
    function KListitem.get_name:string;
    begin
     result:=name;
    end;
    
    function KListitem.get_zuege:string;
    begin
     result:=zuege;
    end;
    
    procedure Tform_main.FormCreate(Sender: TObject);
    begin
     liste:=KListe.create;
    end;
    
    procedure Tform_main.button_einfuegenClick(Sender: TObject);
    var listenelement:KListitem;
    begin
     listenelement:=KListitem.create;
     listenelement.set_name(labelededit_name.text);
     listenelement.set_zuege(labelededit_zuege.text);
     liste.insert_behind(listenelement);
    end;
    
    procedure Tform_main.button_vorClick(Sender: TObject);
    begin
     if not(liste.is_empty) then
     begin
     liste.next;
     labelededit_name.text:=(KListitem(liste.get_inhalt)).get_name;
     labelededit_zuege.text:=(KListitem(liste.get_inhalt)).get_zuege;
     end
     else
     showmessage('Keine Einträge vorhanden');
    end;
    
    procedure Tform_main.button_zurueckClick(Sender: TObject);
    begin
     if not(liste.is_empty) then
     begin
     liste.previous;
     labelededit_name.text:=(KListitem(liste.get_inhalt)).get_name;
     labelededit_zuege.text:=(KListitem(liste.get_inhalt)).get_zuege;
     end
     else
     showmessage('Keine Einträge vorhanden');
    end;
    
    initialization
     {$I uMain.lrs}
    
    end.
    
    Beim Kompilieren spuckt er mir im Hauptprogramm beim klicken zum einfügen nen segfault aus, könnt ihr mir da helfen?...thx4help schomma im vorraus, mfg coach

    PS: ich benutze lazarus und den fp-compiler, also net wundern, wenn delphi das net auf die reihe bekommt, dann müsst ihr entweder die schalter ändern oder einfach die wichtigen sachen in ne neue unit einfügen...

    EDIT: ok, hab nu die initialisierung in den code eingebaut...
     
  2. 31. Oktober 2006
    AW: Problem mit doppelt verketteter liste...

    Poste bitte die komplette Compiler-Meldung... aus deiner Beschreibung werd ich nicht wirklich schlau.
     
  3. 1. November 2006
    AW: Problem mit doppelt verketteter liste...

    sry, mein fehler, nich beim kompilieren gibt er den fehler aus, sondern wenn ich auf den button zum einfügen der eingegebenen daten klicke...mfg coach
     
  4. 1. November 2006
    AW: Problem mit doppelt verketteter liste...

    Code:
    procedure Tform_main.button_einfuegenClick(Sender: TObject);
    var listenelement:KListitem;
    begin
     listenelement.set_name(labelededit_name.text);
     listenelement.set_zuege(labelededit_zuege.text);
     liste.insert_behind(listenelement);
    end;
    ich bin mir nicht sicher, aber musst du nicht auch erst das listenelement initialisieren bevor du seine funktionen und prozeduren aufrufen kannst? Da könnte ein Fehler liegen.
     
  5. 1. November 2006
    AW: Problem mit doppelt verketteter liste...

    nö, das initialisieren beugt afaik nur komische ergebnisse vor, also wenn man meinetwegen ne variable setzt, aber keinen wert zuweist und die dann ausliest würd die dann so datenreste ausm speicher beinhalten...da ich aber direkt die beiden prozeduren zum setzen der attribute aufrufe, dürfte des kein problem sein...mfg coach
     
  6. 1. November 2006
    AW: Problem mit doppelt verketteter liste...

    Das stimmt nicht. Wenn du eine Variable deklarierst, wird auch direkt im Stack Speicher für den Pointer reserviert. Integer z.B brauchst du nicht initialisieren, da der Pointer als Wert verwendet wird, bei Klassen ist jedoch immer eine Initialisierung notwendig. Ausgenommen sind Leere Records, die der Borland Compiler sowiso nicht erlaubt.
     
  7. 2. November 2006
    AW: Problem mit doppelt verketteter liste...

    ok, wieder was gelernt...naja, meine info-lehrer haben halt net sooo den plan^^ aber hast du jetz nen vorschlag, wie ich des am besten behebe? initialisieren bringt nix...mfg coach

    PS: bewertungen für eure mühen geh sofort raus^^
    PPS: daher auch des 'afaik' in meinem beitrag^^
     
  8. 2. November 2006
    AW: Problem mit doppelt verketteter liste...

    Code:
    procedure Tform_main.button_einfuegenClick(Sender: TObject);
    var
     listenelement : KListitem;
    begin
    
     listenelement := KListitem.Create(); //Initialisierung
    
     listenelement.set_name(labelededit_name.text);
     listenelement.set_zuege(labelededit_zuege.text);
     liste.insert_behind(listenelement);
    end;
    
    Wenn hierbei immernoch ein Fehler auftritt, dann mach pls ein Screen.
     
  9. 2. November 2006
    Zuletzt von einem Moderator bearbeitet: 14. April 2017
    AW: Problem mit doppelt verketteter liste...

    {bild-down: https://xup.in/dl,20768942/}

    {img-src: }
    wie gesagt, hab das gefühl, dass des am compiler liegt, also bitte ma in delphi oder so kompilieren...mfg coach

    EDIT: achja, für alle, dies net wissen: diese meldung kommt, nachdem ich auf den button zum einfügen geklickt habe...
     
  10. 4. November 2006
    AW: Problem mit doppelt verketteter liste...

    ~PSUH~...muss doch wen geben, der mir helfen kann...mfg coach
     
  11. 4. November 2006
    AW: Problem mit doppelt verketteter liste...

    Debug einfach, dann weiste ja wo der Fehler auftritt.
     
  12. 4. November 2006
    AW: Problem mit doppelt verketteter liste...

    wenn das so einfach wäre, außerdem tritt der in einer unit auf, die ansich ganz wunderbar funzt (die, in der inttostr steht)...nimm dir doch mal plz die zeit unv versuch des ma zu kompilieren, hab wie schon gesagt das gefühl, dass des am compiler liegt...mfg coach
     
  13. 5. November 2006
    AW: Problem mit doppelt verketteter liste...

    Ich installiere gerade Delphi und schaus mir mal an.

    // EDIT:
    Hab Delphi nu drauf. Lädst du wohl bitte mal dein komplettes Projekt (ohne die exe) hoch damit ichs mir ansehen kann? Habe atm etwas probs mit deinen Bezeichnungen der Form etc. Danke im Voraus.
     
  14. 5. November 2006
    AW: Problem mit doppelt verketteter liste...

    mach ich, aber wie gesagt, is lazarus, net delphi, also net wundern, wenn das net so klappt^^

    Download offline!/

    ...mfg coach
     
  15. 5. November 2006
    AW: Problem mit doppelt verketteter liste...

    hmmm nach dem ich ne weile gebastelt habe konnte ich deinen fehler reproduzieren aber ne lösung für das problem kann ich net finden, sorry ich weiß einfach net wo der fehler liegt, bzw. was genau falsch ist.
     
  16. Video Script

    Videos zum Themenbereich

    * gefundene Videos auf YouTube, anhand der Überschrift.