Entwickler-Ecke
Delphi Language (Object-Pascal) / CLX - Stack-Overflow, Endloschleife?
Juniorsatan - Mo 22.03.10 17:43
Titel: Stack-Overflow, Endloschleife?
Ich probiere mich gerade an einer RLE-Kompression für dynamische Arrays.
Bisher funktionierte die Prozedur mit allen Testarrays, die ich manuell erstellt habe. Generiere ich jedoch ein größeres (wo bspw. die Farbwerte eines Bildes gespeichert sind), kommt es zu einem Stackoverflow.
Die sieht wie folgt aus:
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:
| procedure RLE(kanal_array: Array of Byte); var new_array: Array of Byte; k, count: integer; output:string; begin setlength(new_array, 0); k:=0; While ( k <= length(kanal_array)) DO Begin count:= countrep(kanal_array, k); if (kanal_array[k] = 255) then Begin setlength(new_array, (length(new_array) + 2)); new_array[(high(new_array)-1)]:= 255; new_array[(high(new_array))]:= 0; inc(k) End else if (count > 3) then Begin setlength(new_array, (length(new_array) + 3)); new_array[(high(new_array)-2)]:= 255; new_array[(high(new_array)-1)]:= count; new_array[(high(new_array))]:= kanal_array[k]; k:=(k + count); End Else Begin setlength(new_array, (length(new_array) + 1)); new_array[(high(new_array))]:= kanal_array[k]; inc (k); End; End; setlength(new_array, (length(new_array) - 1));
For k:=0 to high(new_array) DO begin output:= output + inttostr(new_array[k]) + '; '; end;
showmessage(output); end; |
Die Funktion countrep sucht redundante Einträge und sieht so aus:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11:
| function countrep(arr: Array of Byte; k:Integer): Integer; var n:integer; Begin n:=0; While ( ( (k+n) < high(arr) ) AND (arr[(k+n)] = arr[(k+n)+1]) AND (n < 253)) Do Begin inc(n); End; countrep:=n +1 ; End; |
Mich verwirrt wie gesagt der Fakt, dass es für kleine Arrays bisher tadellos funktionierte, Endlosschleifen o.ä. sehe ich auch nirgends. Habt ihr eine Idee?
elundril - Mo 22.03.10 17:52
kann es sein das er sich in der markierten zeile aufhängt weil du mit <= length anstatt mit < length bzw <= high arbeitest?
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:
| procedure RLE(kanal_array: Array of Byte); var new_array: Array of Byte; k, count: integer; output:string; begin setlength(new_array, 0); k:=0; While ( k <= length(kanal_array)) DO Begin count:= countrep(kanal_array, k); if (kanal_array[k] = 255) then Begin setlength(new_array, (length(new_array) + 2)); new_array[(high(new_array)-1)]:= 255; new_array[(high(new_array))]:= 0; inc(k) End else if (count > 3) then Begin setlength(new_array, (length(new_array) + 3)); new_array[(high(new_array)-2)]:= 255; new_array[(high(new_array)-1)]:= count; new_array[(high(new_array))]:= kanal_array[k]; k:=(k + count); End Else Begin setlength(new_array, (length(new_array) + 1)); new_array[(high(new_array))]:= kanal_array[k]; inc (k); End; End; setlength(new_array, (length(new_array) - 1));
For k:=0 to high(new_array) DO begin output:= output + inttostr(new_array[k]) + '; '; end;
showmessage(output); end; |
lg elundril
Juniorsatan - Mo 22.03.10 18:09
Daran habe ich auch schon gedacht, deswegen prüfe ich in der darauffolgenden Funktion sofort, ob ich mich noch im Rahmen des Arrays bewege.
Delphi-Quelltext
1:
| While ( ( (k+n) < high(arr) ) AND ....) Do |
Mir wurde schulischerseits beigebracht, dass es bei solchen Prüfungen wichtig ist, dass diese "vorne" in der Bedingung stehen, sodass bei einem etwaigen Überschreiten die hinteren Expressions nicht mehr angesprochen wird, da es sofort zum Abbruch kommt.
BenBE - Mo 22.03.10 18:40
Dennoch läuft deine äußere Schleife in einen Fall rein, der ohne Behandlung un der inneren Schleife bleibt und damit nie verlassen wird. Schau Dir das doch einmal im Single-Step-Modus (F7/F8) im Debugger an und beobachte die verschiedenen Werte.
Juniorsatan - Mo 22.03.10 18:43
Kann ich das in irgendeiner Weise zumindest ein wenig automatisieren? Das Array ist um die 4000000 Einheiten groß und ich kriege den Fehler bisher nicht anders reproduziert, als das ich das besagte Bild als Ausgangsmaterial verwende.
Nichtsdestotrotz werd ichs mir nochmal angucken.
BenBE - Mo 22.03.10 19:24
Haltepunkt setzen, links auf das rote Mumpel klicken --> Halötepunkt-Eigenschaften und da ne Bedingung eingeben.
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2026 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!