![]() |
Delphi-Version: 2005
EAccessViolence bei Linearer Liste
Hey,
ich arbeite zur Zeit an einem Schulprojekt und komme bei einem Fehler einfach nicht weiter. Ich habe eine FirstIn-FirstOut-Liste, bei der Elemente hinzugefügt und gelöscht werden. Für Hilfe bin ich wirklich dankbar. :cry: Listendefinition:
Delphi-Quellcode:
Hinzufügen von Elementen
type
Zeiger = ^elementtyp; elementtyp = record Zeit_Kunde_an: integer; Zeit_Kunde_noetig: integer; ref: Zeiger; end;
Delphi-Quellcode:
Löschen von Elementen
procedure FiFo(Anker: Zeiger);
var p, q: Zeiger; stop: integer; begin stop := GetTickCount; while ((GetTickCount) < (stop + 1600)) and (Form1.Aufhoeren.checked=false) do begin new(q); q^.ref := nil; q^.Zeit_Kunde_an := GetTickCount; q^.Zeit_Kunde_noetig := 1000; if Anker = nil then Anker := q else p^.ref := q; //Hier war früher eine EAccessViolation - auf wundersame Weise verschwunden p := q; Form1.K1_Z.caption := IntToStr(StrToInt(Form1.K1_Z.caption) + 1); Pausieren(400); end; end;
Delphi-Quellcode:
Viele Grüße und danke schonmal
procedure Bearbeitung();
var K_Z_noetig: integer; p: Zeiger; begin while Form1.Aufhoeren.checked = false do begin if (StrToINt(Form1.K1_Z.Caption) > 0) and (Form1.Aufhoeren.checked = false) then begin K_Z_noetig := K1_A^.Zeit_Kunde_noetig; Pausieren(K_Z_noetig); p := K1_A; K1_A := K1_A^.ref; //HIER tritt sie jetzt auf dispose(p); Form1.K1_Z.caption := IntToStr(StrToInt(Form1.K1_Z.caption) - 1); end else Pausieren(400); end; end; Riclem |
AW: EAccessViolence bei Linearer Liste
Das
Delphi-Quellcode:
Argument muss schonmal als
Anker
Delphi-Quellcode:
deklariert werden, damit die Zuweisung
var Anker: Zeiger
Delphi-Quellcode:
durchgeführt werden kann. Die markierte Zeile knallt deshalb, weil zu diesem Zeitpunkt
Anker := q
Delphi-Quellcode:
noch nicht initialisiert ist.
p
Delphi-Quellcode:
geht deshalb ins Leere. Es war vermutlich
p^.ref
Delphi-Quellcode:
gewollt.
Anker^.ref := q
|
AW: EAccessViolence bei Linearer Liste
Ah klar stimmt, das
Delphi-Quellcode:
muss da natürlich hin. Zur Initialisierung von p: Da
VAR
Delphi-Quellcode:
im else-Zweig steht, wird es erst beim zweiten Durchgang ausgeführt. Dann ist es doch über
p^.ref := q;
Delphi-Quellcode:
schon initialisiert?
p:=q;
Hast du vielleicht für die zweite markierte Zeile noch eine Idee? Vielen Dank bisher!! |
AW: EAccessViolence bei Linearer Liste
Zitat:
Delphi-Quellcode:
initial immer
Anker
Delphi-Quellcode:
ist. Dein Funktionsdesign (insbesondere die Logik deiner Funktionskapselung) ist leicht unintuitiv :lol:
nil
An der zweiten Stelle wird
Delphi-Quellcode:
zu irgendeinem Zeitpunkt wohl
K1_A
Delphi-Quellcode:
sein. Warum, weshalb, sehe ich grade im Gewurschtel der globalen Variablen und missbrauchten GUI Controls leider nicht.
nil
|
AW: EAccessViolence bei Linearer Liste
Haha, ja so kann man das wohl nennen :D Dann werde ich das wohl selber suchen müssen. Sag mal, was bedeutet denn so eine EAccessViolation eigentlich so? Bei mir trat sie auf beim:
- Auslesen eines Elements der Liste - bei Anweisungen à la x:=y^.ref Gibt es da irgendwie bestimmte Ursachen oder so? Vielen Dank :-D |
AW: EAccessViolence bei Linearer Liste
Eine Access Violation tritt immer dann auf, wenn du versuchst auf einen ungültigen Speicherbereich zuzugreifen (lesend oder schreiben). Ungültig ist ein Speicherbereich dann, wenn er vorher nicht allocated wurde.
Sowas passiert häuftig, wenn man beispielsweise mit Objekten arbeitet und vorher den
Delphi-Quellcode:
Aufruf vergessen hat, oder wenn man Objekte bereits mit
Create
Delphi-Quellcode:
wieder zerstört hat, aber danach noch mit Ihnen arbeiten will. In deinem Falle ist die fehlerhafte Pointer-Arithmetik Schuld (präziser gesagt, wird dein Zeiger irgendwann entweder auf
Free
Delphi-Quellcode:
, oder eine andere nicht existente Speicherstelle zeigen. Sobald du dann mit
nil
Delphi-Quellcode:
dereferenzierst, knallt es).
^
Generell ist es btw. immer eine gute Idee, Funktionalitäten in Klassen zu kapseln. Hier wäre auf die Schnelle mal eine an deine Delphi Version (keine Standard-Queue-Klasse, keine Generics) angepasste Implementierung einer FIFO-Liste (Queue):
Delphi-Quellcode:
Auch ist es eigentlich immer schlecht, wenn man Business-Logik in die GUI reinwurschtelt. So ein Label als Counter zu verwenden, ist ein No-Go :P Dafür ist es einfach nicht gemacht, was man schon an deinem umständlichen
type
TQueueData = record public Foo: Integer; Bar: String; end; TQueue = class(TObject) strict private type PQueueItem = ^TQueueItem; TQueueItem = record public FLink: PQueueItem; BLink: PQueueItem; Data: TQueueData; end; strict private FFirst: PQueueItem; FLast: PQueueItem; FCount: Integer; public procedure Enqueue(const Data: TQueueData); function Dequeue: TQueueData; function Peek: TQueueData; procedure Clear; public destructor Destroy; override; public property Count: Integer read FCount; end; { TQueue } procedure TQueue.Clear; var Temp: PQueueItem; begin while Assigned(FFirst) do begin Temp := FFirst^.FLink; Dispose(FFirst); FFirst := Temp; end; FLast := nil; FCount := 0; end; function TQueue.Dequeue: TQueueData; var Temp: PQueueItem; begin if (FCount = 0) then raise Exception.Create('No items in queue'); Result := FFirst^.Data; Temp := FFirst^.FLink; Dispose(FFirst); if Assigned(Temp) then begin Temp^.BLink := nil; FFirst := Temp; end else begin FFirst := nil; FLast := nil; end; Dec(FCount); end; destructor TQueue.Destroy; begin Clear; inherited; end; procedure TQueue.Enqueue(const Data: TQueueData); var Item: PQueueItem; begin New(Item); Item^.FLink := nil; Item^.BLink := FLast; Item^.Data := Data; if (not Assigned(FFirst)) then begin FFirst := Item; end; if Assigned(FLast) then begin FLast^.FLink := Item; end; FLast := Item; Inc(FCount); end; function TQueue.Peek: TQueueData; begin if (FCount = 0) then raise Exception.Create('No items in queue'); Result := FFirst^.Data; end;
Delphi-Quellcode:
und
StrToInt
Delphi-Quellcode:
Gemenge sieht.
IntToStr
|
AW: EAccessViolence bei Linearer Liste
Wow super, vielen Dank. Jetzt klappt es :)
Danke, schönen Sonntag noch! |
Alle Zeitangaben in WEZ +1. Es ist jetzt 15:57 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