AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Sprachen und Entwicklungsumgebungen Sonstige Fragen zu Delphi Access Violation mit einfach verketteter Liste

Access Violation mit einfach verketteter Liste

Ein Thema von Hybrid666 · begonnen am 19. Sep 2010 · letzter Beitrag vom 19. Sep 2010
Antwort Antwort
Seite 1 von 2  1 2   
Hybrid666

Registriert seit: 15. Jul 2006
Ort: Erster Stock
250 Beiträge
 
Delphi 7 Personal
 
#1

Access Violation mit einfach verketteter Liste

  Alt 19. Sep 2010, 18:51
Moin,

ich habe folgende Struktur meiner Daten:
Delphi-Quellcode:
  PCommandList = ^TCommandList;
  TCommandList = record
    InputName : Integer;
    Pressed : Boolean;
    Next : PCommandList;
  end;

  PMakroList = ^TMakroList;
  TMakroList = record
    TimeStamp : Integer;
    Commands : PCommandList;
    Next : PMakroList;
  end;
Im Prinzip soll das einfach eine Einfach verktettete Liste sein (PMakroList), die eine Reihe von Commands enthält (PCommandList), auch als einfach verkettete Liste.

Das Anlegen der Liste funktioniert einwandfrei und ich habe auch eine Routine in meinem Objekt, das die Struktur speichern soll. Dazu habe ich folgenden Code:

Delphi-Quellcode:
procedure TMakro.SaveToFile(FileName : String);
var
  MRef : PMakroList;
  CRef : PCommandList;
  SaveFile : TextFile;
  I : Integer;
begin
  AssignFile (SaveFile, FileName);
  ReWrite (SaveFile);
  WriteLn (SaveFile, 'ÿNAME' + MakroName);
  WriteLn (SaveFile, 'ÿBEGINDESCRIPTION');
  for I := 0 to Description.Count - 1 do
    writeln (SaveFile, Description[I]);
  WriteLn (SaveFile, 'ÿENDDESCRIPTION');
  WriteLn (SaveFile, 'ÿBEGINMAKRO');
  MRef := Makro;
  while Assigned (MRef) do
  begin
    WriteLn (SaveFile, 'T' + IntToStr (MRef.TimeStamp));
    CRef := MRef.Commands;
    while Assigned (CRef) do
    begin
      writeln (SaveFile, IntToStr (CRef.InputName) + '|' + BoolToStr (CRef.Pressed, True));
      CRef := CRef.Next;
    end;
    MRef := MRef.Next;
  end;
  writeln (SaveFile, 'ÿENDMAKRO');
  CloseFile (SaveFile);

end;
(über den stil sowas zu speichern lässt sich streiten, daher bitte keine große diskussion drüber).

Wie man sieht wird einfach eine Textdatei hergenommen, erst diverse Optionen (name, beschreibung) von dem Objekt gespeichert und dann gehts an die List. Eigentlich dachte ich, dass ich genug kontrollabfragen drin hab, sodass ich nie ins leere laufen kann. Es sei noch gesagt, das alle leeren pointer mit "nil" initialisiert werden beim anlegen, damits bei assigned auch keine probleme gibt.

Nun tritt sporadisch (immer mal wieder) an folgender Stelle ein fehler auf:
WriteLn (SaveFile, 'T' + IntToStr (MRef.TimeStamp)) Und zwar ist der fehler eine Access violation. Ich gehe davon aus, das er auf MRef nicht zugreiffen kann. aber wo ist da mein fehler, bzw wo fehlt die kontrolle?

Danke für die Hilfe

Hybrid

Geändert von Hybrid666 (19. Sep 2010 um 20:24 Uhr) Grund: Code-Tags durch Delphi-Tags ersetzt
  Mit Zitat antworten Zitat
mkinzler
(Moderator)

Registriert seit: 9. Dez 2005
Ort: Heilbronn
39.820 Beiträge
 
Delphi 10.4 Sydney
 
#2

AW: Bekomme einen Error (sporadisch)

  Alt 19. Sep 2010, 18:54
Überprüfe doch ob der Zeiger <> Nil is (Assigned())
Markus Kinzler
  Mit Zitat antworten Zitat
Hybrid666

Registriert seit: 15. Jul 2006
Ort: Erster Stock
250 Beiträge
 
Delphi 7 Personal
 
#3

AW: Bekomme einen Error (sporadisch)

  Alt 19. Sep 2010, 18:56
Sollte doch eigentlich
Code:
while Assigned (MRef) do
tun, oder?
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
39.180 Beiträge
 
Delphi 10.4 Sydney
 
#4

AW: Bekomme einen Error (sporadisch)

  Alt 19. Sep 2010, 18:58
Abgesehn von der fehlenden Fehlerbehandlung für SaveFile,
welches aber mit diesem Problem nichts zu tun hat,
dürfte dieser Code OK sein,


also vermute ich eher einen Fehler beim Erstellen dieser Listen.


Und ja, bei Pointern entpicht Assigned(P) einem P <> nil .
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
Delphi-Tage 2005-2014
  Mit Zitat antworten Zitat
mkinzler
(Moderator)

Registriert seit: 9. Dez 2005
Ort: Heilbronn
39.820 Beiträge
 
Delphi 10.4 Sydney
 
#5

AW: Bekomme einen Error (sporadisch)

  Alt 19. Sep 2010, 18:59
Eher if Assigned( MRef) then ... oder if not Assigned( MRef) then Exit;
Markus Kinzler
  Mit Zitat antworten Zitat
Hybrid666

Registriert seit: 15. Jul 2006
Ort: Erster Stock
250 Beiträge
 
Delphi 7 Personal
 
#6

AW: Bekomme einen Error (sporadisch)

  Alt 19. Sep 2010, 19:01
Hier ist der Code zum einfügen in die liste. Das ist der einzige Codeteil, der änderungen an der liste vornimmt:
Delphi-Quellcode:
procedure TMakro.AddInput (Pressed : Boolean; Name : Integer);
begin
  //Liste komplett leer
  if Makro = nil then
  begin
    new (Makro);
    Makro.Next := nil;
    RefMakro := Makro;
    new (RefMakro.Commands);
    Makro.TimeStamp := TimeStamp;
    RefCommand := Makro.Commands;
    Makro.Commands.InputName := Name;
    Makro.Commands.Pressed := Pressed;
  end
  else
  // TimeStamp existiert schon, also nur command in command liste einfügen
  begin
    if TimeStamp = RefMakro.TimeStamp then
    begin
      new (RefCommand.Next);
      RefCommand := RefCommand.Next;
      RefCommand.Next := nil;
      RefCommand.InputName := Name;
      RefCommand.Pressed := Pressed;
    end
    else
    // Timestamp größer als momentaner Referenztimestamp, also neuer Makro-Listen-Eintrag + neuen command einfügen
    begin
      new (RefMakro.Next);
      RefMakro := RefMakro.Next;
      RefMakro.Next := nil;
      RefMakro.TimeStamp := TimeStamp;
      new (RefMakro.Commands);
      RefCommand := RefMakro.Commands;
      RefCommand.Next := nil;
      RefCommand.InputName := Name;
      RefCommand.Pressed := Pressed;
    end;
  end;
end;
Zu sagen: Die Variablen Makro und TimeStamp existieren als private in der Klasse TMakro. TimeStamp ist ein Integer und Makro ist PMakroList. RefCommand und RefMakro existieren ebenfalls als private.

Geändert von mkinzler (19. Sep 2010 um 19:03 Uhr) Grund: Code-Tag durch Delphi-Tag ersetzt; Was habt ihr alle gegen den Delphi-Tag?
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
39.180 Beiträge
 
Delphi 10.4 Sydney
 
#7

AW: Bekomme einen Error (sporadisch)

  Alt 19. Sep 2010, 19:06
hmmmm, also wenn es wieder mal zu dieser Exception kommt, dann schau dir doch einfach im Debugger die Listen an.
Und vorallem die Stelle, an welcher dieses Problem auftreten tut.
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
Delphi-Tage 2005-2014
  Mit Zitat antworten Zitat
Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#8

AW: Bekomme einen Error (sporadisch)

  Alt 19. Sep 2010, 19:07
Da er aber schon prüft, ob das Object assigned ist, vermute ich, dass sich da ein Zeiger einschleicht, der zwar noch auch einer ehemaligen Struktur steht, diese Struktur ist aber schon wieder freigegeben. Der Zeiger wird dadurch ja nicht automatisch auf nil gesetzt.

Kapsel doch mal die Zugriffe mit try ... except und schau nach, bei welchem Object er diese Zicken macht und ob du evtl. da vorher was gelöscht hast.

Was auch gerne passiert:

Ein Object wird doppelt in eine Liste eingetragen. Dann einmal Free und aus der Liste gelöscht und fertig ist der Zugriffsfehler bei dem immer noch existierenden Eintrag in der Liste.
Delphi-Quellcode:
var
  objlst : TObjectList;
  obj : TObject;
begin
  objlst := TObjectList.Create;
  try
    obj := TObject.Create;
    objlst.Add( obj );
    objlst.Add( obj );
    objlst.Delete( 0 );
  finally
  end;
end;
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)
  Mit Zitat antworten Zitat
Hybrid666

Registriert seit: 15. Jul 2006
Ort: Erster Stock
250 Beiträge
 
Delphi 7 Personal
 
#9

AW: Bekomme einen Error (sporadisch)

  Alt 19. Sep 2010, 19:08
peinliche frage: ich hab noch nie mit nem debugger geschafft. was nimmt man da und wie schau ich mir die listen an?

Danke!
  Mit Zitat antworten Zitat
mkinzler
(Moderator)

Registriert seit: 9. Dez 2005
Ort: Heilbronn
39.820 Beiträge
 
Delphi 10.4 Sydney
 
#10

AW: Bekomme einen Error (sporadisch)

  Alt 19. Sep 2010, 19:13
Einfach Breakpoint an der Stelle setzen (oder kurz vorher) dann hält der Debugger hier an. Dann kannst du die Variablen durch Hinzufügen als überwachte Ausdrücke oder durch Überfahren mit der Maus auswerten
Markus Kinzler
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2   

Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 15:32 Uhr.
Powered by vBulletin® Copyright ©2000 - 2022, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2021 by Daniel R. Wolf