Entwickler-Ecke
Algorithmen, Optimierung und Assembler - Delete-Routine von verketteter Liste erzeugt AV
Marco D. - Mi 14.02.07 17:12
Titel: Delete-Routine von verketteter Liste erzeugt AV
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61:
| procedure TAttributelist.Delete(index: integer); var i: integer; begin if (index <= High) and (index > -1) then begin if (FCount = 1) then begin FreeAndNil(FFirst.Data); FFirst.Next := nil; FFirst := nil; FCurrently := nil; end else begin if (index = 0) then begin FreeAndNil(FFirst.Data); for i := 0 to High do begin SetPointerAtPosition(i); if (i <> High) then FCurrently := FCurrently.Next else FCurrently := nil; end; end else begin SetPointerAtPosition(index); FreeAndNil(FCurrently.Data); for i := index to High do begin SetPointerAtPosition(i); if (i <> High) then FCurrently := FCurrently.Next else FCurrently := nil; end; end; end; dec(FCount); showmessage(explode); end; end;
procedure TAttributelist.SetPointerAtPosition(index: integer); var i: integer; begin if (index <= High) and (FFirst <> nil) then begin FCurrently := FFirst; i := 0; while (i < index) do begin FCurrently := FCurrently.Next; inc(i); end; end; end; |
Wenn ich zwei Einträge hinzufüge und dann Delete(0) aufrufe, also den ersten Eintrag löschen will, gibt es eine AV.
Findet ihr den Fehler?
Delete - Mi 14.02.07 17:16
ohne mich einzudenken, ist mir folgendes an deinen code aufgefallen.
- du gibtst das objekt frei
- anschliessend greifst du auf das objekt zu, um die pointer zu verschieben
hier solltest mal die sequenz umstellen, erst die pointer umhängen, dann erst das objekt welches die pointer beherbergt freigeben. <HTH>
Marco D. - Mi 14.02.07 17:22
Grenzgaenger hat folgendes geschrieben: |
ohne mich einzudenken, ist mir folgendes an deinen code aufgefallen.
- du gibtst das objekt frei
- anschliessend greifst du auf das objekt zu, um die pointer zu verschieben
hier solltest mal die sequenz umstellen, erst die pointer umhängen, dann erst das objekt welches die pointer beherbergt freigeben. <HTH> |
Ich greife bei deinem zweiten Punkt nicht auf das Objekt zu. Das Objekt ist wie gesagt frei gegeben.
Das Objekt (Data) enthält ja nicht die Pointer:
Delphi-Quelltext
1: 2: 3: 4: 5:
| PItem = ^TItem; TItem = record Data: TAttribute; Next: PItem; end; |
Delete - Mi 14.02.07 17:27
was ist z.b. hiermit:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13:
| procedure TAttributelist.Delete(index: integer); var i: integer; begin if (index <= High) and (index > -1) then begin if (FCount = 1) then begin FreeAndNil(FFirst.Data); FFirst.Next := nil; FFirst := nil; FCurrently := nil; end |
oder wo gibst du sonst dein objekt/record frei? im anderen falle, würdest du dir ja nur den hauptspeicher zumüllen..
Marco D. - Mi 14.02.07 17:30
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13:
| procedure TAttributelist.Delete(index: integer); var i: integer; begin if (index <= High) and (index > -1) then begin if (FCount = 1) then begin FreeAndNil(FFirst.Data); FFirst.Next := nil; FFirst := nil; FCurrently := nil; end |
:zwinker:
Dieser Abschnitt funzt ja, das habe ich schon getestet.
Poste hier nochmal eine neuere Version der Routine. Der Fehlerbereich ist markiert.
Es crasht, wenn ich zwei oder mehr Einträge habe und den ersten löschen will.
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40:
| procedure TAttributelist.Delete(index: integer); var ptemp: PItem; begin if (FFirst <> nil) then begin if (index = 0) then begin if (Count = 1) then begin FreeAndNil(FFIrst.Data); FFirst := nil; FCurrently := nil; end else begin SetPointerAtPosition(index); showmessage(FCUrrently.Data.Name); FreeAndNil(FCurrently.Data); FCurrently := FCurrently.Next; FCurrently.Next := nil; end; end else if (index < High) then begin SetPointerAtPosition(index); ptemp := FCurrently.Next; FreeAndNil(FCurrently.Data); FCurrently.Next := nil; SetPointerAtPosition(index - 1); FCurrently.Next := ptemp; end; dec(FCount); Changed; end; end; |
Marco D. - Mi 14.02.07 19:31
Man ey :P Jetzt funktioniert's :party:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36:
| procedure TAttributelist.Delete(index: integer); var ptemp: PItem; begin if (FFirst <> nil) then begin if (index = 0) then begin if (Count = 1) then begin FreeAndNil(FFIrst.Data); FFirst := nil; FCurrently := nil; end else begin FreeAndNil(FFirst.Data); FFirst := FFirst.Next end; end else if (index < High) then begin SetPointerAtPosition(index); ptemp := FCurrently.Next; FreeAndNil(FCurrently.Data); FCurrently.Next := nil; SetPointerAtPosition(index - 1); FCurrently.Next := ptemp; end; dec(FCount); Changed; end; end; |
Sorry für das Schiebeposting 8)
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2025 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!