Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Lazarus (IDE) (https://www.delphipraxis.net/81-lazarus-ide/)
-   -   Löschen aus der StringList verursacht Fehler, wieso? (https://www.delphipraxis.net/185234-loeschen-aus-der-stringlist-verursacht-fehler-wieso.html)

AlexII 23. Mai 2015 21:14


Löschen aus der StringList verursacht Fehler, wieso?
 
Hallo,

ich lösche wie folgt aus einer StringList, aber immer beim letztem oder vorletztem Item bricht das Programm zusammen, da "List index (x) out of bounds"
Ich verstehe nicht wieso... wird der Count etwa runtergezählt? Wie kann man sich das anders erklären, oder mache ich was falsch?

Delphi-Quellcode:
procedure TMainForm.DeleteFromErrorList(pvErrorCode: String);
var
  i, p: Integer;
begin
  if gvErrorReportList.Count > 0 then
  begin
    for i := 0 to gvErrorReportList.Count - 1 do
    begin
      p := Pos(ErrorCode, gvErrorReportList.Strings[i]);
      if p <> 0 then
      begin
        gvErrorReportList.Delete(i);
      end;
    end;
  end;

end;
Danke!

Luckie 23. Mai 2015 21:21

AW: Löschen aus der StringList verursacht Fehler, wieso?
 
Du löscht von oben weg. Aber in der for-Scheife wird Count nicht jedes mal wieder neu berechnet. Ergo es knallt, weil Count noch den Wert x hat aber nur noch x-1 Einträge vorhanden sind.

Lass die Schleife rückwärts laufen.

AlexII 23. Mai 2015 21:24

AW: Löschen aus der StringList verursacht Fehler, wieso?
 
Ok... und das Löschen von unten löst das so wie ich das verstehe, oder? Mit einer while-Schleife? OK, danke!

Popov 23. Mai 2015 21:25

AW: Löschen aus der StringList verursacht Fehler, wieso?
 
Du musst eines bedenken: nehmen wir an du hast eine StringList mit 10 Items, also Count = 10.

Nun gehst du mit
Delphi-Quellcode:
For To Do
0 bist 9 durch. Das ist der Wert von Count - 1 am Anfang. Das merkt sich die
Delphi-Quellcode:
For To Do
Schleife. Sie merkt sich die Zahl 9 und geht alle 10 Werte durch. Aber mitten drin löscht du Items aus der StringList. Nach dem ersten Löschvorgang gibt es nur noch 9 Items, nach dem zweiten 8, bei dem dritten 7, vierten 6, fünften 5, sechsten (das wäre dann i = 5) hätte die StringList nur noch 4 Items. Spätestens hier greifst du auf einen Item den es nicht mehr gibt.

Lösung: nicht
Delphi-Quellcode:
for i := 0 to gvErrorReportList.Count - 1 do
sondern
Delphi-Quellcode:
for i := gvErrorReportList.Count - 1 downto 0 do
. In dem Fall gehst du von oben nach unten und überschreitest nie die Grenze.

Luckie 23. Mai 2015 21:26

AW: Löschen aus der StringList verursacht Fehler, wieso?
 
Eben nicht. Das ist ja das Problem.

Popov 23. Mai 2015 21:28

AW: Löschen aus der StringList verursacht Fehler, wieso?
 
Erklärung?

Luckie 23. Mai 2015 21:31

AW: Löschen aus der StringList verursacht Fehler, wieso?
 
Die haben wir beide doch schon geliefert.

Perlsau 23. Mai 2015 21:40

AW: Löschen aus der StringList verursacht Fehler, wieso?
 
Ich glaube, das Mißverständnis besteht darin, daß Luckie mit seinem "Eben nicht" auf das Posting von AlexII geantwortet hat und nicht auf das von Popov. Passiert manchmal, wenn einer "zwischenrein" postet :-D

Dieses Beispiel funktioniert korrekt (eben schnell in CodeTyphon getippt und getestet):
Delphi-Quellcode:
procedure TFormMain.Button2Click(Sender: TObject);
Var
  Liste : TStringList;
  i    : Integer;
begin
  Liste := TStringList.Create;

  Try
    For i := 1 To 10 Do
        Liste.Append('Eintrag ' + IntToStr(i));
    ShowMessage('Listen-Zahl = ' + IntToStr(Liste.Count));
    For i := Liste.Count -1 DownTo 0 Do
        Liste.Delete(i);
  Finally
    ShowMessage('Listen-Zahl = ' + IntToStr(Liste.Count));
    Liste.Free;
  End;
end;

Popov 23. Mai 2015 21:41

AW: Löschen aus der StringList verursacht Fehler, wieso?
 
Das "Eben nicht" hat mich irritiert. Weiß nicht auf welchen Post es bezogen ist.

AlexII 23. Mai 2015 21:49

AW: Löschen aus der StringList verursacht Fehler, wieso?
 
Man, man, voll easy... muss nur bisschen nachdenken... und selber solche Problemchen lösen. Vielen Dank euch!

Perlsau 23. Mai 2015 21:54

AW: Löschen aus der StringList verursacht Fehler, wieso?
 
Ich denk mal, wenn du dranbleibst und dich regelmäßig mit Delphi bzw. Lazarus oder CodeTyphon (erweiterte Lazarus-IDE, aus meiner Sicht sehr zu empfehlen) befaßt, wird das schon. Das geht dir mit der Zeit quasi in Fleisch & Blut über und du träumst dann vielleicht sogar davon :lol:

Popov 23. Mai 2015 22:06

AW: Löschen aus der StringList verursacht Fehler, wieso?
 
Zitat:

Zitat von AlexII (Beitrag 1302858)
Man, man, voll easy... muss nur bisschen nachdenken... und selber solche Problemchen lösen. Vielen Dank euch!

Tröste dich. Auch wenn ich mich hier etwas aus dem Fenster lehne, so behaupte ich mal, dass das Vorwärts-Löschen von Items in der For-Schleife ein Fehler-Klassiker ist und irgendwann jedem passiert ist.

himitsu 23. Mai 2015 23:19

AW: Löschen aus der StringList verursacht Fehler, wieso?
 
Zitat:

Zitat von AlexII (Beitrag 1302840)
Ich verstehe nicht wieso...

Du könntes auch mal den Debugger benutzen und nachsehn. :roll:

Zitat:

Zitat von AlexII (Beitrag 1302840)
wird der Count etwa runtergezählt?

Wie bereits gesagt wurde, zählt Count zwar runter, aber die For-Schleife cached das Schleifenende. (es wird immer nur einmal zu Beginn ausgewertet)

Aber selbst wenn es das nicht zwischenspeichern würde, dann hättest du ein Problem, da du bei einer For-Schleife Einträge überspringt, wenn du was löschst, da die Schleife erbarmunglos hochzählt, aber die Einträge nach dem Gelöschten verschoben werden.

Also entweder rückwärts oder mit While-Schleife, egal wie rum, aber bei Vorwärts dort natürlich den Index nicht hochzählen, wenn grade gelöscht wurde.


PS: Das IF vor dem FOR kannst'e dir sparen, denn wenn die Liste leer ist, dann heißt es
Delphi-Quellcode:
for i := 0 to {count}0 - 1 do // 0 bis -1
// oder
for i := {count}0 - 1 downto 0 do
und das macht dann natürlich nichst.


Alle Zeitangaben in WEZ +1. Es ist jetzt 05:16 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz